Мне было любопытно, что такое большая структура по сравнению с небольшой структурой при использовании операторов +
и *
для математики.Итак, я создал две структуры: одну Small
с 1 двойным полем (8 байт) и одну Big
с 10 двойными (80 байт).Во всех моих операциях я манипулирую только одним полем с именем x
.
Сначала я определил в обеих структурах математические операторы, такие как
public static Small operator +(Small a, Small b)
{
return new Small(a.x + b.x);
}
public static Small operator *(double x, Small a)
{
return new Small(x * a.x);
}
, которые, как и ожидалось, занимают много памяти в стеке.для копирования полей вокруг.Я выполнил 5 000 000 итераций математической операции и получил то, что подозревал (замедление в 3 раза).
public double TestSmall()
{
pt.Start(); // pt = performance timing object
Small r = new Small(rnd.NextDouble()); //rnd = Random number generator
for (int i = 0; i < N; i++)
{
a = 0.6 * a + 0.4 * r; // a is a local field of type Small
}
pt.Stop();
return pt.ElapsedSeconds;
}
результаты из кода выпуска (в секундах)
Small=0.33940 Big=0.98909 Big is Slower by x2.91
Теперь для интересной части,Я определяю те же операции со статическими методами с ref
аргументами
public static void Add(ref Small a, ref Small b, ref Small res)
{
res.x = a.x + b.x;
}
public static void Scale(double x, ref Small a, ref Small res)
{
res.x = x * a.x;
}
и выполняю такое же количество итераций для этого кода теста:
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;
}
И результаты показывают (в секундах))
Small=0.11765 Big=0.07130 Big is Slower by x0.61
Таким образом, по сравнению с операторами интенсивного копирования в память, я получаю ускорение x3 и x14, что замечательно, но сравните времена структуры Small с Big, и вы увидите, что Small - 60% медленнее чем Большой.
Может кто-нибудь объяснить это?Имеет ли это отношение к конвейеру ЦП, а разделение операций в (пространственно) памяти обеспечивает более эффективную предварительную выборку данных?
Если вы хотите попробовать это сами, возьмите код из моего выпадающего списка http://dl.dropbox.com/u/11487099/SmallBigCompare.zip