2017-06-27 1 views
-1

私はg ++ -O3が自動的に除算を乗算に変更すると考えました。しかし、このコードにaccroding:g ++ -O3が除算を乗算に変更しないのはなぜですか?

#include <iostream> 
#include <sys/time.h> 

double compute0(int i) { 
    double d_2 = i * i; 
    double ret = 0; 
    for (int j = 0; j < 1000000; j++) { 
    ret += j; 
    } 
    return ret; 
} 

double compute1(int i) { 
    double d_2 = i * i; 
    double ret = 0; 
    for (int j = 0; j < 1000000; j++) { 
    ret += j/d_2; 
    } 
    return ret; 
} 

double compute2(int i) { 
    double d_2 = i * i; 
    double d_2_inv = 1.0/d_2; 
    double ret = 0; 
    for (int j = 0; j < 1000000; j++) { 
    ret += j * d_2_inv; 
    } 
    return ret; 
} 

double tik() { 
    struct timeval tv; 
    gettimeofday(&tv, NULL); 
    return tv.tv_sec + tv.tv_usec * 1e-6; 
} 

int main() { 
    { 
    double begin = tik(); 
    double ret = 0; 
    for(int i = 1; i < 100; i++) 
     ret += compute0(i); 
    double end = tik(); 
    std::cout << "cost time: " << end - begin << " ret: " << ret << std::endl; 
    } 
    { 
    double begin = tik(); 
    double ret = 0; 
    for(int i = 1; i < 100; i++) 
     ret += compute1(i); 
    double end = tik(); 
    std::cout << "cost time: " << end - begin << " ret: " << ret << std::endl; 
    } 
    { 
    double begin = tik(); 
    double ret = 0; 
    for(int i = 1; i < 100; i++) 
     ret += compute2(i); 
    double end = tik(); 
    std::cout << "cost time: " << end - begin << " ret: " << ret << std::endl; 
    } 
    return 0; 
} 

出力は次のとおり

費用時間:0.105436 RET:4.95e + 13

費用時間:0.453676 RET:8.17441e + 11

コスト時間:0.203873 ret:8.17441e + 11

なぜですか?

+1

あなたは '-ffast-math'を忘れました。 –

+4

コンパイルコマンドを表示します。たとえば、次のようにコンパイルして最適化を有効にしましたか? 'g ++ -Wall -O2'とは?生成されたアセンブラコードを調べました( 'g ++ -Wall -O2 -fverbose-asm -S'を使い、生成された' .s'ファイルを調べてください)。 **あなたの質問を編集して**改善する(またはあなたの質問を削除する) –

答えて

1

通常、コンパイラはIEEE754に従います。この規格では、除算は正確に定義されています。それは、すべてのa/bに対して、少し正確な答えがあることを意味します。これをa*(1/b)に変更した場合、結果は少し異なることがあります(16桁の数字でダブルを印刷すると、この効果が見られる場合があります)。

コンパイラは通常これを緩和するオプションを持っています。 GCCには-fast-math、VCには/ fp:fastがあります。

関連する問題