0

gettimeofday() を使用する単純な C プログラムは、フラグなし (gcc-4.5.1) でコンパイルすると正常に動作しますが、フラグ -mno-sse でコンパイルすると出力が得られません。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    struct timeval s,e;
    float time;
    int i;
    gettimeofday(&s, NULL);
    for( i=0; i< 10000; i++);
    gettimeofday(&e, NULL);
    time = e.tv_sec - s.tv_sec + e.tv_usec - s.tv_usec;
    printf("%f\n", time);
    return 0;
}

私は CFLAGS=-march=native -mtune=native を持っています 誰かがなぜこれが起こるのか説明できますか? 通常、プログラムは正しい値を返しますが、-mno-sse を有効にしてコンパイルすると、「0」が出力されます。

4

4 に答える 4

5

このフラグ-mno-sseにより​​、浮動小数点引数がスタックに渡されますが、通常のx86_64 ABIは、SSEレジスタを介して渡される必要があることを指定します。

printf()Cライブラリでは、なし でコンパイルされているため-mno-sse、ABIに従って浮動小数点引数が渡されることが期待されます。これが、コードが失敗する理由です。とは何の関係もありませんgettimeofday()

printf()でコンパイルされたコードから使用し-mno-sseて浮動小数点引数を渡す場合は、そのオプションを使用してCライブラリを再コンパイルし、そのバージョンにリンクする必要があります。

于 2010-09-11T14:33:38.870 に答える
1

時間差を観察するために何もしないループを使用しているようです。問題は、コンパイラがこのループを完全に最適化する可能性があることです。問題は-mno-sseそれ自体にあるわけではありませんが、ループを削除する最適化が可能になるため、実行するたびに同じ時間が得られる可能性があります。

最適化できないものをそのループに入れることをお勧めします(最後に出力する数値をインクリメントするなど)。それでも同じ動作が得られるかどうかを確認してください。そうでない場合は、生成されたアセンブラgcc -Sを見て、コードの違いを確認することをお勧めします。

于 2010-09-10T20:18:58.643 に答える
1

データ構造 tv_usec と tv_sec は通常 long です。変数「time」を長整数として再宣言すると、問題が解決しました。

次のリンクは、この問題に対処しています。 http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00525.html 作業コード:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    struct timeval s,e;
    long time;
    int i;
    gettimeofday(&s, NULL);
    for( i=0; i< 10000; i++);
    gettimeofday(&e, NULL);
    time = e.tv_sec - s.tv_sec + e.tv_usec - s.tv_usec;
    printf("%ld\n", time);
    return 0;
}

迅速な返信ありがとうございます。お役に立てれば。

于 2010-09-11T06:51:28.213 に答える
0

どういう意味doesn't give outputですか?

0 (ゼロ) は、期待するのに完全に妥当な出力です。


編集: アセンブラー ( gcc -S ...) にコンパイルしてみて、通常のバージョンと no-sse バージョンの違いを確認してください。

于 2010-09-10T19:54:55.063 に答える