Решил замерить скорость выполнения операции деления, умножения и сложения на разных типах данных.
Создал тестовый цикл из 500 млн. одинаковых операций (деления).
Развернул цикл, довольно значительно - http://ru.wikipedia.org/wiki/Размотка_цикла
Скомпилировал Release-версию с выключенными оптимизациями, запустил... получил довольно странные результаты...
В этом тесте вообще смысла нет. С оптимизацией(без которой программу в релиз пускать нет смысла) операции над элементарными типами данных производятся практически моментально, из-за таких наборов инструкций, как, например, SSE. Ты мог бы до этого додуматься сам.
Не, ну такие адовые тесты гонять на операционке с вытесняющей многозадачностью и без сбора статистики по тысяче попыток - это явно неправильно. Ну и проблема теста в его лютой синтетичности. Довольно сложно разработать алгоритм, который будет вычислять что-то полезное только с помощью математических операций внутри ядра. Разве что число pi считать, да и то его выгружать придётся. Можно попробовать решить какое-нибудь лду итеративно. На современных процессорах гораздо большая проблема не в том, чтобы что-то посчитать, а в подтаскивании//оттаскивании данных обычно.
операции над элементарными типами данных производятся практически моментально, из-за таких наборов инструкций, как, например, SSE
С одной махонькой поправочкой - ГРУППОВЫЕ операции с элементарными типами данных.
Как это часто бывает в реальных алгоритмах, операции происходят над ОДИНОЧНЫМИ числами, а не над векторами(массивами) чисел.
c4tnt :
Ну и проблема теста в его лютой синтетичности.
Ну а почему все-таки операции над интами происходят медленнее операций с флоатами, мне так никто и не объяснил
Сплошная философия.
P.S. Сейчас делаю алгоритм, который работает с (предварительно заполненным) массивом рандомных чисел...
Если можно оперировать только с одиночными числами, а в вектор они никак не собираются, то это значит что либо в алгоритме ещё килограмм ветвлений на квадратный сантиметр кода, либо есть только один вычислительный блок, результаты которого зависят от вычисления предыдущего блока. В тесте, кстати, результат следующего вычисления от предыдущего не зависит, поэтому fpu могло довольно быстро асинхронно считать целые стопки чисел. Это надо дизасм смотреть опять же. Второй вариант - сделать тестируемую зону с использованием _asm вставки чтобы всё однозначно было.
Ну а почему все-таки операции над интами происходят медленнее операций с флоатами, мне так никто и не объяснил
Листинг на ассемблере нужен чтобы такое объяснять.
Переделал алгоритм под массивы, заполненные случайными числами... результат выглядит намного более вразумительно:
(видимо, кэширование данных решало в прошлом примере)
void test_float2()
{
float res;
for (int j=0; j<500; ++j)
for (int i=0; i
res = floats[i]/floats[i+1];
res = floats[i+2]/floats[i+3];
res = floats[i+4]/floats[i+5];
res = floats[i+6]/floats[i+7];
res = floats[i+8]/floats[i+9];
}
}
, т.е. деление выполняется 500 миллионов раз.
(и это отбирает 4922 ticks на моем процессоре)
Тогда можно предположить, что компилятор умный и умеет хорошо распоряжаться FPU стэком. И в первом случае он не перезагружал значения в стэк, так как не было необходимости. Кстати, для того, чтобы вычисления с переменной реально проводились, желательно ставить на неё volatile. С другой стороны это чревато memory barrier в обе стороны от переменной и сильному замедлению в итоге.