0

FLT_MIN シームによって制限される結果につながる浮動小数点乗算は、他の浮動小数点乗算と比較して非常に遅くなります。以下のサンプル コードを Linux マシンで実行すると、次の結果が得られました。

Elapsed time for 1E09 iterations of  0 * 0.900000 : 2.623269 s 
Elapsed time for 1E09 iterations of  1.17549e-38 * 0.900000 : 73.851011 s 
Elapsed time for 1E09 iterations of  2.35099e-38 * 0.900000 : 2.637788 s 
Elapsed time for 1E09 iterations of  0.00870937 * 0.900000 : 2.632788 s 
Elapsed time for 1E09 iterations of  1 * 0.900000 :  2.654571 s 
Elapsed time for 1E09 iterations of  3.40282e+38 * 0.900000 : 2.639316 s 

演算 1.17549e-38 * 0.9 は、テストされた他の乗算演算よりも少なくとも 25 倍長くかかるようです。これはよく知られている問題ですか?

FLT_MIN につながる可能性のある多数の乗算を実行する必要があるタイム クリティカルなプロジェクトでは、この問題を回避するための迅速な方法は何でしょうか? (乗算する前にすべての値をチェックする余裕はありませんが、乗算結果の e-5 のオーダーの誤差は許容できます)

#include <sys/time.h>
#include <stdio.h>
#include <float.h>
#define N_VALS 6
#define ALMOST_MIN FLT_MIN*2
int timeval_subtract (struct timeval *result,struct timeval * start,struct timeval *stop)
{
  long int sdiff= stop-> tv_sec - start->tv_sec;
  long int udiff=stop->tv_usec - start-> tv_usec;
  if (udiff<0)
  {
    udiff=1000000+udiff;
    sdiff--;
  }
  result->tv_sec = sdiff;
  result->tv_usec = udiff;  
}

int main()
{
  float values [N_VALS]={0.0f,FLT_MIN,ALMOST_MIN, 0.00870937f, 1.0f, FLT_MAX};
  float out, mul=0.9f;
  int i, j, err;
  struct timeval t_start, t_stop, t_elaps;
  for (j=0; j<N_VALS; j++)
  {
    err=gettimeofday(&t_start, NULL);
    for (i=0; i<1000000000; i++)
      out=values[j]*mul;

    err=gettimeofday(&t_stop, NULL);
    timeval_subtract(&t_elaps, &t_start, &t_stop);
    printf("Elapsed time for 1E09 iterations of  %g * %f : %ld.%06ld s \n", values[j], mul, t_elaps.tv_sec, t_elaps.tv_usec);
  }
}
4

1 に答える 1

1

.9 * FLT_MIN を実行するのにはるかに時間がかかる理由は、結果が float で表現できる最小値よりも小さいためです。これにより、プロセッサは例外を発生させます。これは OS によって処理され、ユーザー空間で関数を呼び出す場合があります。完全にハードウェアで実行される単純な浮動小数点乗算と比較すると、これには長い時間がかかります。

修正方法は?プラットフォームとビルド ツールによって異なります。gcc を使用している場合、設定したフラグに応じて、CPU 設定を使用して一部の操作を最適化しようとします。-ffast-math および関連する浮動小数点最適化フラグについては、gcc マニュアルを参照してください。これらのフラグを使用すると、IEEE 浮動小数点仕様に正確に準拠しない結果が生じる可能性があることに注意してください。

于 2014-01-19T14:22:46.310 に答える