1

Power6 クラスターで Altivec 拡張機能をいじっていました。最適化を行わずに以下のコードをコンパイルすると、期待どおりにスピードアップが 4 であることに気付きました。しかし、-O3 フラグを付けて再度コンパイルしたところ、60 倍の高速化が実現しました。

誰かがこれについてもっと経験があり、コンパイラが私のコードをどのように再配置してそのようなスピードアップを実行しているかについての洞察を提供できるかどうか疑問に思っています. ここでのアセンブリと命令パイプラインによる唯一の可能な最適化ですか、それとも、今後の作業に含めることができる欠けているものが他にありますか?

int main(void) {
        const int m = 1000;

        __vector signed int va;
        __vector signed int vb;
        __vector signed int vc;
        __vector signed int vd;

        int a[m];
        int b[m];
        int c[m];

        for( int i=0 ; i < m ; i++ ) {
                a[i] = i;
                b[i] = i;
                c[i] = 0;
        }

        for( int cnt = 0 ; cnt < 10000000 ; cnt++ ) {
                vd = (__vector signed int){cnt,cnt,cnt,cnt};

                for( int i = 0 ; i < m/4 ; i+=4 ) {
                        va = vec_ld(0, &a[i]);
                        vb = vec_ld(0, &b[i]);
                        vc = vec_add(vd, vec_add(va,vb));
                        vec_st(vc, 0, &c[i]);
                }
        }

        std::cout << c[0] << ", " << c[1] << ", " << c[2] << ", " << c[3] << "\n";

        return 0;
}
4

1 に答える 1

4

私は Power 7 でいくつかの作業を行いましたが、XLC コンパイラーで非常に奇妙なことがわかりました。しかし、これほど奇妙ではありません!(少なくとも60倍ではない...)

PowerPC シリーズ (少なくとも Power6 と Power7 の場合) について注意すべきことの 1 つは、x86/x64 に比べて命令のレイテンシが非常に長く、アウトオブオーダーの実行が非常に弱いことです。

したがって、(コードに記述されているように) 内側のループの IPC は非常に低くなります。

さて、私が想像できる唯一の方法は、内部ループが-O3 の下で完全に展開されることです。これが可能なのは、内側のループのトリップ カウントが 63 であると静的に決定できるためです。

その内側のループを展開すると、基本的にパイプライン全体が満たされるようになります。

もちろん、私はただ推測しています。あなたの最善の策は、アセンブリを見ることです。

また、そのタイミングはどのようにしていますか?私が PowerPC で見た奇妙な動作の多くは、タイマー自体によるものです...

編集:

サンプル コードは非常に単純なので、(アセンブリ内で) 内部ループが部分的に展開されているか完全に展開されているかを簡単に見つけることができます。

于 2011-09-16T03:20:49.777 に答える