Я выполнил бенчмаркинг, чтобы сравнить удвоение и производительность поплавка. Я был очень удивлен, увидев, что удваивается намного быстрее, чем плавает.Возможно ли, что удваивается x2 FASTER, чем float?
Я видел некоторые дискуссии о том, что, например:
Is using double faster than float?
Are doubles faster than floats in c#?
Большинство из них сказал, что это возможно, что двойные и плывут производительность будет похоже, из-за двойной точности оптимизация и т. д. Но я видел улучшение производительности x2 при использовании двухместных !! Как это возможно? Хуже всего то, что я использую 32-битную машину, которая, как ожидается, будет лучше работать для поплавков в соответствии с некоторыми сообщениями ...
Я использовал C# для проверки, но я вижу, что аналогичная реализация на C++ имеет аналогичное поведение.
код я, чтобы проверить его:
static void Main(string[] args)
{
double[,] doubles = new double[64, 64];
float[,] floats = new float[64, 64];
System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
s.Restart();
CalcDoubles(doubles);
s.Stop();
long doubleTime = s.ElapsedMilliseconds;
s.Restart();
CalcFloats(floats);
s.Stop();
long floatTime = s.ElapsedMilliseconds;
Console.WriteLine("Doubles time: " + doubleTime + " ms");
Console.WriteLine("Floats time: " + floatTime + " ms");
}
private static void CalcDoubles(double[,] arr)
{
unsafe
{
fixed (double* p = arr)
{
for (int b = 0; b < 192 * 12; ++b)
{
for (int i = 0; i < 64; ++i)
{
for (int j = 0; j < 64; ++j)
{
double* addr = (p + i * 64 + j);
double arrij = *addr;
arrij = arrij == 0 ? 1.0f/(i * j) : arrij * (double)i/j;
*addr = arrij;
}
}
}
}
}
}
private static void CalcFloats(float[,] arr)
{
unsafe
{
fixed (float* p = arr)
{
for (int b = 0; b < 192 * 12; ++b)
{
for (int i = 0; i < 64; ++i)
{
for (int j = 0; j < 64; ++j)
{
float* addr = (p + i * 64 + j);
float arrij = *addr;
arrij = arrij == 0 ? 1.0f/(i * j) : arrij * (float)i/j;
*addr = arrij;
}
}
}
}
}
}
Я использую очень слабый ноутбук: процессор Intel Atom N455 (двухъядерный, 1.67GHz, 32bit) с 2 Гб оперативной памяти.
Спасибо за ответ. Обратите внимание, что счетчик увеличивается в одном и том же смещении как для двоек, так и для поплавков (он вычисляется вручную в цикле for). – MaMazav
Вам не нужен небезопасный код, чтобы воспроизвести это. Эффект исчезает, если вы удалите назначение обратно в массив. – Zong
Вы правы, это происходит и на моей машине. И почему так? Может быть, политика кэширования обратной записи/написания (как, возможно, ранее говорилось)? – MaMazav