I was curious about the overhead of a large structure versus a small structure when using the + and * operators for math. Thus, I created two structures, one Small with 1 double field (8 bytes) and one Big with 10 doubles (80 bytes). In all my operations, I control only one field x .
First, I defined mathematical operators in both structures, like
public static Small operator +(Small a, Small b) { return new Small(ax + bx); } public static Small operator *(double x, Small a) { return new Small(x * ax); }
which is expected to use a lot of memory on the stack to copy fields around. I run 5,000,000 iterations of a mathematical operation and got what I suspected (3x slowdown).
public double TestSmall() { pt.Start();
release code result (in seconds)
Small=0.33940 Big=0.98909 Big is Slower by x2.91
Now for the interesting part. I define the same operations with static methods with ref arguments
public static void Add(ref Small a, ref Small b, ref Small res) { res.x = ax + bx; } public static void Scale(double x, ref Small a, ref Small res) { res.x = x * ax; }
and run the same number of iterations in this test code:
public double TestSmall2() { pt.Start(); // pt = performance timing object Small a1 = new Small(); // local Small a2 = new Small(); // local Small r = new Small(rnd.NextDouble()); //rdn = Random number generator for (int i = 0; i < N; i++) { Small.Scale(0.6, ref a, ref a1); Small.Scale(0.4, ref r, ref a2); Small.Add(ref a1, ref a2, ref a); } pt.Stop(); return pt.ElapsedSeconds; }
And the results show (in seconds)
Small=0.11765 Big=0.07130 Big is Slower by x0.61
Thus, compared to intensive mem-copy statements, I get x3 and x14 acceleration, which is great, but compare Small struct times with Big and you will see that Small is 60% slower than Big.
Can anyone explain this? Do I need to do this with the CPU pipeline and separate operations in (spatial) memory to provide more efficient data prefetching?
If you want to try this for yourself, grab the code from my dropbox http://dl.dropbox.com/u/11487099/SmallBigCompare.zip