Расчет FLops
Я пишу программу для подсчета времени, которое требуется моему ЦП для выполнения одного "FLops". Для этого я написал код ниже
before = clock();
y= 4.8;
x= 2.3;
z= 0;
for (i = 0; i < MAX; ++i){
z=x*y+z;
}
printf("%1.20f\n", ( (clock()-before )/CLOCKS_PER_SEC )/MAX);
Проблема в том, что я повторяю ту же операцию. Разве компилятор не оптимизирует такого рода "вещи"? Если так, что я должен сделать, чтобы получить правильные результаты?
Я не использую функцию "rand", поэтому она не противоречит моему результату.
2 ответа
Это имеет переносимую в цикле зависимость и недостаточно для параллельного выполнения чего-либо, поэтому, если что-то вообще будет выполнено, то вы не будете измерять FLOP, с этим вы, вероятно, будете измерять задержку сложения с плавающей запятой. Цепочка зависимостей, переносимая циклом, сериализует все эти дополнения. В этой цепочке есть несколько маленьких боковых цепочек с умножениями, но они ни от чего не зависят, поэтому важна только их пропускная способность. Но эта пропускная способность будет лучше, чем задержка добавления на любом разумном процессоре.
Для фактического измерения FLOP нет единого рецепта. Оптимальные условия сильно зависят от микроархитектуры. Количество независимых цепочек зависимостей, которые вам нужны, оптимальное отношение сложения / умножения, следует ли вам использовать FMA, все зависит. Обычно вам нужно сделать что-то более сложное, чем то, что вы написали, и если вы настроены на использование языка высокого уровня, вы должны каким-то образом обмануть его, чтобы вообще что-то делать.
Для вдохновения посмотрите, как мне достичь теоретического максимума 4 FLOP за цикл?
Даже если у вас не идет оптимизация компилятора (возможности уже были хорошо перечислены), ваши переменные и результат будут в кеше после первой итерации цикла и с этого момента вы на дорожке с гораздо большей скоростью и производительностью, чем вы были бы, если программе придется получать новые значения для каждой итерации.
Поэтому, если вы хотите рассчитать время для одного флопа для одной итерации этой программы, вам фактически придется вводить новые данные для каждой итерации. Действительно подумайте об использовании rand() и просто начните с известным значением srand(1)
или так.
Ваши расчеты также должны быть другими; флопс - это количество вычислений, которые ваша программа делает в вашем случае 2*n (где n = MAX). Для расчета количества времени на флоп делим время, используемое на количество флопов.