0

最近、FLOPS を計算する簡単なプログラムを作成しようとしています。十分に速いのでc++、近い結果を出すために試してみる価値があると思います。
Notepad++ プラグインでコンパイルすると、NppExec正常に動作しますが、ビルドしません。CodeBlocks でビルドして実行すると、反復が続き、プロセスが完了しません。そのため、notepad++ に戻って再度コンパイルすると、今回は正常に動作し、反復が 1 秒経過しただけです。

 #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;
  }

結果をより正確にする方法を知っている場合は、先に進んでください。どんな回答でも大歓迎です!

4

1 に答える 1

1

このコードには多くの問題があります。まずfloat変数 ( j) を使用して、ループのカウンターを厳密な終了条件で維持していますj<999999999。これがおそらく、ループが永久に実行される理由です。の型は、 のjような整数型でなければなりませんint

次に、ループ内のフロップの数は、使用しているコンパイラ、コンパイラに渡すコンパイラ オプション、およびターゲット アーキテクチャによって異なります。これを理解する最善の方法は、生成されたアセンブリ コードを確認することです。

3 番目に、 の最初の呼び出しclockと の 2 番目の呼び出しのclock順序が変更され、結果が無効になるコンパイラの最適化が原因である可能性があります。アセンブリ コードを見て、並べ替えられていないことを確認する必要があります。これを確実にする方法は、コンパイラによって異なります。

4番目、これはどういう意味ですか?

flop=999999;   // Actually is 999999999, but integer overflow in expression

コンパイラは999999999、オーバーフローが発生することを通知していますか? はいの場合、ループ終了条件でどのように使用していますか? エラーは正確には何ですか?

、これ

if(flop/1000000000>=1||flop/1000000000<1){

おそらくこうあるべき

if(flop/1000000000>=1){

6番目に、ループの後に使用していないため、ループ全体がコンパイラによって最適化されてしまう可能性がありvarます。varこれが起こらないように、最後にの値を出力する必要があります。

7番目に、式a*b+a/bには定数値があります。varしたがって、実際には、すべての反復に同じ値が割り当てられます。コンパイラは、これを単一の定数割り当てに最適化する場合があります。この場合、ゼロフロップが発行されます。

8番目に、ここのコメントは、乗算ではなく除算と言う必要があります。

flop/=secs;    // To get the Flops in second, multiply with time elapsed

9番目、この条件はこの条件のif(flop/1000000000000>=1)前に来るべきですif(flop/1000000000>=1)

10 番目、このコード行では、Floating-pointと呼ばれています

cout<<"\n\n\n Floating-points Operations Per Second\n\n

11 番目に、この数値999999999は変更しやすいように、関数の先頭で定数として定義する必要があります。

最後に、実行時間を計算するために使用した方法は最も単純で、多くの場合に十分です。しかし、はるかに正確な、はるかに複雑な方法があります。

于 2015-07-05T09:12:47.713 に答える