5

C変換先とパーツに単純magnitudeなループがあります。ループとして 2 つのバージョンがあります。次のコードを使用して変換を実行する単純な for ループですanglerealimaginaryVersion 1

for(k = 0; k < n; k++){
    xReal[k] = Mag[k] * cos(Angle[k]);
    xImag[k] = Mag[k] * sin(Angle[k]);
}

Version 2whereIntrinsicsは、ループをベクトル化するために使用されます。

__m256d cosVec, sinVec;
__m256d resultReal, resultImag;
__m256d angVec, voltVec;
for(k = 0; k < SysData->totNumOfBus; k+=4){

    voltVec = _mm256_loadu_pd(volt + k);
    angVec = _mm256_loadu_pd(theta + k);

    sinVec = _mm256_sincos_pd(&cosVec, angVec);

    resultImag = _mm256_mul_pd(voltVec, sinVec);
    resultReal = _mm256_mul_pd(voltVec, cosVec);

    _mm256_store_pd(xReal+k, resultReal);
    _mm256_store_pd(xImag+k, resultImag);

}

プロセッサではCore i7 2600k @3.4GHz、これらのループにより次の結果が得られます。

Version 1: n = 18562320, Time: 0.2sec
Version 2: n = 18562320, Time: 0.16sec

これらの値を使用した単純な計算は、version 1では、各反復が完了するのにほぼ36サイクルかかるのに対し、完了するのに117サイクルかかることを示していVersion 2ます。sineand関数の計算は当然コストがかかるという事実を考えるとcosine、これらの数値はそれほどひどいものではないように思われます。1/3ただし、プロファイリングではほとんどの時間がループ内で費やされていることが示されるため、このループは私の関数の深刻なボトルネックです。したがって、このループを促進する方法があるかどうか疑問に思っています (たとえば、計算sinecosine機能が異なります)。この問題を回避し、このループのパフォーマンスを改善する余地があるかどうかを教えていただければ幸いです。

よろしくお願いいたします。

PS:iccコードのコンパイルに使用しています。また、データが整列されていない (そして整列できない) ことにも言及する必要があります。ただし、データを整列してもパフォーマンスはわずかに向上します (1% 未満)。

4

3 に答える 3

0

リストするタイミング結果は、バージョン 2 がバージョン 1 と比較してより高速に (20%) 実行されることを示しています。

Version 1: n = 18562320, Time: 0.2sec
Version 2: n = 18562320, Time: 0.16sec

各バージョンで使用されるサイクルをどのように計算しているかわかりませんか? v1 が使用するサイクルが少ない場合でも、プロセッサで多くの作業が行われ、キャッシュ フェッチによって時間に違いが生じる可能性があります (これも、サイクルをどのようにカウントしたかわかりません)。

または、別の説明として、ベクトル化により、メモリ フェッチの待機時間なしでデータ要素を利用できるということです。

于 2013-08-13T06:10:42.787 に答える