2017-01-16 2 views
9

です私たちが整数引数を持っている%ではなくfmodの使用をなぜ疑問に思っていますか?なぜなら、なぜですか?はいくつかの古いSRCコードに次の行を見つけ整数係数の計算のための速い%よりFMOD

int e = (matrix[i]) % n; 

fmod%以上に選択するとパフォーマンス上の理由があるのでしょうか、それともちょっと変わったコードですか?

+3

'fmod'は' double'に変換されて戻される浮動小数点値を使用しています。だから:** no **。整数演算の場合は、 '%'演算子を使用してください。 –

+0

prob何かが遅い?私は、C文から対応するアセンブリを生成することはあまりできませんが、fmodを% – bph

答えて

2

はおそらくfmod%オーバー を選択するか、それがコードのちょうど奇妙なビットであるため、パフォーマンス上の理由があるだろうか?

fmodは少し速く〜50サイクル以上、そうfmodの関数呼び出しとint <---> double変換のコストを償却することができます(たとえば)かかり高遅延IDIV命令、とのアーキテクチャ上のかもしれません。

Agner's Fog instruction tablesによれば、AMD K10アーキテクチャのIDIVは24~55サイクルかかる。現代のIntel Haswellと比較すると、レイテンシの範囲は22-29サイクルとなっていますが、依存関係のチェーンがない場合は、インテルの8~11クロックサイクルでは逆のスループットがはるかに優れています。

1

実験(および非常に反直感的)、fmod%より速い - 少なくともAMDのPhenom(TM)II X4 955 6400とBogoMips値に。

#include <math.h> 
#include <stdio.h> 

int main() 
{ 
    int volatile a=10,b=12; 
    int i, sum = 0; 
    for (i = 0; i < 1000000000; i++) 
     sum += a % b; 
    printf("%d\n", sum); 
    return 0; 
} 

時間の実行::9.07秒をここでの手法のいずれかを使用する2つのプログラム、両方が同じコンパイラ(GCC)と同じオプション(cc -O3 foo.c -lm)でコンパイルされ、同じハードウェア上で実行しましたがされています。

#include <math.h> 
#include <stdio.h> 

int main() 
{ 
    int volatile a=10,b=12; 
    int i, sum = 0; 
    for (i = 0; i < 1000000000; i++) 
     sum += (int)fmod(a, b); 
    printf("%d\n", sum); 
    return 0; 
} 

実行時間:8.04秒

+1

以上使用すると、もっと面白いと思います。私はquesionに尋ねてうれしく思います。 – bph

+4

私のシステムでは、バージョン1は3.07秒で動作し、バージョン2は8.97秒で動作します。だから私は大きなマージンを持って反対の結果を得る。あなたが使用している正確なハードウェアや、その他さまざまなものに大きく依存することになります。 –

+1

@DietrichEpp好奇心のために、どのCPUを使用しましたか?私はCPUが低速だと思うが、FPUは大丈夫だと思う。 – DyZ

1

fmodは、選択したアーキテクチャの整数除算よりも少し速いかもしれません。

注しかしnは、コンパイル時に知られている非ゼロ値を有する場合、matrix[i] % n整数モジュラスおよび浮動小数点モジュラスのいずれよりもはるかに高速でなければならない小さな調整、との乗算としてコンパイルされること。

もう1つ興味深い違いは、n == 0INT_MIN % -1の動作です。整数モジュラス演算はオーバーフロー時に未定義の動作を呼び出し、多くの現在のアーキテクチャ上でプログラムが異常終了する結果になります。逆に、浮動小数点弾性率は、これらのコーナーケースを有していない、結果は、-Infinity+InfinityあるNanmatrix[i]-INT_MIN、すべてintの範囲と背面intに実装定義されている変換を超える値に応じて、通常はしません異常なプログラムの終了を引き起こします。これは、元のプログラマーがこの驚くべき解決方法を選択した理由です。

+0

私の特定のシナリオでは、n> 0、通常<〜1000であり、コンパイル時定数ではありません。私は%のfmodを交換しました。私のインテルでは、私は40%のスピードアップを見ました。さらなる洞察をいただきありがとう – bph

関連する問題