• 締切済み

足し算の計算速度

こんにちは。 足し算の計算速度を測ってみました。 すると、全く同じ条件で、足す値だけ変えてみると 計算速度が変わりました。 具体的には、ガウス分布を単純に台形公式で積分したのですが、 積分範囲と平均値を固定して、分散を小さくすると 積分時間が異常に長くなりました。 小さい値(10e-200)とかの足し算は遅くなるのですか? また、理由もあれば教えていただけないでしょうか? 宜しくお願いします。

みんなの回答

  • chirubou
  • ベストアンサー率37% (189/502)
回答No.5

再度No.2 です。 No.3 さんの回答に戸惑ってしまいました。他の回答者さんの回答に補足するのは気が引けたのと、確認する時間が必要でした。 Intel の Pentium4 のデータシートで確認しましたが、少なくとも FADD に関しては1クロック(正確にはパイプラインなので1クロックという表現は微妙ですが)でした。 No.3 さんがご指摘は、処理としては全く正しいのですが、昔よりも複雑なハードが設計できるようになった結果、現在の大半のプロセッサでは浮動小数点の積および和に関しては1クロックでできます。 さて、質問者さんの質問にもどりますが、私も惑わされていましたが、どうして「足し算の計算速度」の問題となったのでしょう?補足で示されたプログラム片では「かけ算」もあるようですが。 ついでながら、割り算に関しては、割り算を全て行う回路は未だ発明されていませんので、遥かに時間がかかります。Pentium 4 で 30 クロック前後掛かるようです。ただ最近はコンパイラが賢いので不必要な割り算コードが多く出ているとは考え難いです。数値計算で一番問題になるのはキャッシュの効率ですね。

  • TT414
  • ベストアンサー率18% (72/384)
回答No.4

No.3の追加です。 5.3e10+(-2.99e10)の場合、(3-2.99)e10=0.01e10=1e8ですが、最後の0.01e10=1e8の変換に時間がかかります。

  • TT414
  • ベストアンサー率18% (72/384)
回答No.3

float,doubleの場合、指数部の等しい数の加算と、指数部が違う場合で計算速度が違います。 実際は2進数ですが、説明の都合上10進数で説明します。 1.3e10+4e10の場合、(3+4)e10=7e10で計算できます。 2.3e10+8e10の場合、(3+8)e10=11e10=1.1e11ですが、最後の11e10=1.1e11の変換に時間がかかります。 3.3e10+4e20の場合、(0.0000000003+4)e20=3.0000000003e20としなければ計算できません、3を0.0000000003に変換するのに時間がかかります。 4.3e10+10e-200の場合、答えは3e10ですので計算しません。 要するに、指数部がある程度近い場合などの時に遅くなります。

  • chirubou
  • ベストアンサー率37% (189/502)
回答No.2

足し算自体は基本的には1クロックで計算できるはずで、足す/足される数の値によって計算時間が変わることはありません。 ただし、値がキャッシュに入っているかどうかでは、計算速度に大きな差がでます。ひとつのプログラムの実行の中で、条件を替えるような場合、1回目の実行でキャッシュにデータが乗るため、2回目以降では計算速度が速くなったりします。これをさけるには、一番最初に計測しないで、1回実行してから(これでキャッシュに乗る)、計測するといいと思います。ただ、キャッシュという観点からすると、積分範囲が小さい方が有利になるハズなので、今回の原因とは違うかもしれません。 計算速度の計測というのは結構難しいものです。Linux だとたまたま他のデーモンが動いていたりして、遅くなったりします。何回も計測して値にばらつきがあるようでしたら、これを疑ってください。正確に計測する時は、不要なデーモンは停止させるか、デーモンの影響を小さくするため計算時間を十分長くする必要があります。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

コンパイラと実行環境、それに実際に足し算を行っている部分のソースコード(およびそこに現れるオブジェクトの型)を補足してください。 また、計算速度の計測方法も補足してください。

0123456789A
質問者

補足

言語がfortranなので(fortranカテはないのでこちらで聞いてしまいました) アルゴリズムを説明します。 至ってシンプルで、ループ内で再帰計算するだけです。 その中で一度だけ外部関数を呼び出します。一応ソースを書いておきます。 do i = 1,imax x1 = xmin-(xmax-xmin)*dble(i-1)/dble(imax-1) x2 = xmin-(xmax-xmin)*dble(i)/dble(imax-1) k= (func(x1)+func(x2))*(x2-x1)/2.0 res = res + k end do funcがユーザー定義の外部関数です。 i,imaxは整数、x1,x2,k,res,xmax,xminは倍精度実数変数、funcは倍精度実数関数です。 コンパイラ:mpif77(ただし並列計算は行わない) 実行環境:Linux(CPU=Pen4,Mem=2GB) 時間計測はスケジューラが計算します。 宜しくお願いします。