1

パフォーマンスを改善しようとしている非常に単純なプログラムがあります。私が知っている 1 つの方法は、SSE3 を利用することです (私が作業しているマシンはこれをサポートしているため) が、これを行う方法がまったくわかりません。コード スニペット (c++) は次のとおりです。

int sum1, sum2, sum3, sum4;
for (int i=0; i<length; i+=4) {
  for (int j=0; j<length; j+=4) {
    sum1 = sum1 + input->value[i][j];
    sum2 = sum2 + input->value[i+1][j+1];
    sum3 = sum3 + input->value[i+2][j+3];
    sum4 = sum4 + input->value[i+3][j+4];    
  {
}

私はこれについて少し読んで、その考えを理解しましたが、これを実装する方法がまったくわかりません。誰か助けてくれませんか?特に私の単純なプログラムの場合、これはかなり単純だと思いますが、開始するのが最も難しい場合があります。

ありがとう!

4

1 に答える 1

5

実際、あなたの場合、それほど単純ではありません。現状では、コードはベクトル化できません。(少なくとも、重要なループ変換がないわけではありません)

iこれは、内側のループ内でもインデックスを変更しているためです。メモリ位置が隣接しておらず、行列の異なる行にあるため、繰り返しをベクトル化できる可能性がjなくなります。(マトリックスを斜めに実行しているように見えるため)

ただし、マトリックス内のすべての要素を合計しようとしているように感じます。実際には、ループを次のようにすることを意図していました (また、多くのタイプミスもありました)。

int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0;
for (int i=0; i<length; i++) {
  for (int j=0; j<length; j+=4) {
    sum1 = sum1 + input->value[i][j];
    sum2 = sum2 + input->value[i][j+1];
    sum3 = sum3 + input->value[i][j+2];
    sum4 = sum4 + input->value[i][j+3];    
  }
}

int total = sum1 + sum2 + sum3 + sum4;

これがあなたの望むものなら、非常にベクトル化可能です。組み込み関数を使用する C/C++ では、SSE2 のみを使用して次のように実行できます。

__m128i sum = _mm_setzero_si128();
for (int i=0; i<length; i++) {
  for (int j=0; j<length; j+=4) {
    __m128i val = _mm_load_si128(&input->value[i][j]);
    sum = _mm_add_epi32(sum,val);
  }
}

配置制限が適用されることに注意してください。また、ループをさらに展開することで、さらに多くのスピードアップを得ることができます。

于 2011-11-02T05:43:05.563 に答える