Я недавно пытался сделать простую программу, которая рассчитывает FLOPS. поскольку c++
достаточно быстрый, поэтому я думаю, что стоит попытаться получить близкий результат.
Когда я компилирую его с помощью плагинов Notepad ++, NppExec
, это работает нормально, но я не строю это. Когда я собираю и запускаю в CodeBlocks, он продолжает повторяться и не завершит процесс. Итак, я возвращаюсь в notepad ++ и снова скомпилирую его, затем, когда я запускаю его, он работает нормально, итерация просто прошла секунду.
#include<iostream>
#include<conio.h>
#include<ctime>
#include<iomanip>
using namespace std;
int main(){
float a=1.0,b=2.0,var,j;
double flop;
clock_t start,end;
cout<<"\n Iterating...";
start=clock();
for(j=0;j<999999999;j++){ // Iterates 999999999 times
var=a*b+a/b; // <-- 5 Flops, or am I wrong?
}
end=clock();
cout<<"\n\n Calculating...";
double secs=((float)(end-start))/CLOCKS_PER_SEC;
flop=999999; // Actually is 999999999, but integer overflow in expression
flop=5*(flop*1000+999); // In the brackets I make the value to same as 999999999
// Multiply with 5 and basically get Flops here
flop/=secs; // To get the Flops in second, multiply with time elapsed
string prefix,fstr;
if(flop/1000000000>=1||flop/1000000000<1){
flop/=1000000000;
prefix="GFLOPS";
}
else if(flop/1000000000000>=1){
flop/=1000000000000;
prefix="TFLOPS";
}
cout<<"\n\n\n Floating-points Operations Per Second\n\n > "<<setprecision(3)<<flop<<" "<<prefix;
getch();
return 0;
}
Если вы знаете, как сделать результат более точным, любой ответ будет оценен по достоинству!
Есть много проблем с этим кодом. Первый, вы используете float
переменная (j
) поддерживать счетчик цикла со строгим условием завершения j<999999999
, Это, вероятно, причина, по которой цикл может работать вечно. Тип j
должен быть целочисленным типом, таким как int
,
второй, количество флопов в цикле зависит от используемого компилятора, опций компилятора, которые вы передаете компилятору, и целевой архитектуры. Лучший способ понять это — увидеть сгенерированный код сборки.
В третьих, первый звонок clock
и второй звонок clock
может быть переупорядочено из-за оптимизации компилятора, делающей результаты недействительными. Вы должны убедиться, что они не были переупорядочены, посмотрев код сборки. Способ обеспечить это зависит от компилятора.
четвертый, что это значит?
flop=999999; // Actually is 999999999, but integer overflow in expression
Компилятор говорит вам, что 999999999
приводит к переполнению? Если да, то как вы используете его в условии завершения цикла? В чем именно ошибка?
пятый, этот
if(flop/1000000000>=1||flop/1000000000<1){
должно быть так
if(flop/1000000000>=1){
шестой, весь цикл может быть оптимизирован компилятором, потому что вы не используете var
после петли. Вы должны напечатать значение var
в конце концов, так не бывает.
Седьмой, выражение a*b+a/b
имеет постоянное значение. Таким образом, практически, то же значение присваивается var
каждая итерация Компилятор может оптимизировать это для одного константного присваивания. В этом случае будут выпущены ноль флопов.
Восьмой, комментарий здесь должен сказать, делить, а не умножать.
flop/=secs; // To get the Flops in second, multiply with time elapsed
девятый, это условие if(flop/1000000000000>=1)
должен прийти до этого условия if(flop/1000000000>=1)
десятый, в этой строке кода это называется Плавающая запятая
cout<<"\n\n\n Floating-points Operations Per Second\n\n
одиннадцатый, этот номер 999999999
должен быть определен как константа в начале функции, чтобы ее было легче изменить.
в заключение, метод, который вы использовали для вычисления времени выполнения, является самым простым и достаточно хорошим во многих случаях. Но есть гораздо более сложные методы, которые гораздо более точны.