0

私は、次のような単純なビットスクランブリングループをclang ++自動ベクトル化しようとしています:

for(int i = 0; i < sz; ++i) {
   dst[i] = src[i] ^ key[i]
}

とが同じ長さの場合dst、コンパイラはこのループをベクトル化しても問題ありませんが、私が本当にやりたいことは次のとおりです。srckey

for(int i = 0; i < sz; ++i) {
   dst[i] = src[i] ^ key[i % 64];
}

キーをデータほど長くする必要はありませんが% 64、ベクトライザーを追加すると、通常のループが発生します。これ% 8は、SIMD レジスタのサイズであっても発生します。私が次に試したのはこれでした:

char d = 0x80
for(int i = 0; i < sz; ++i) {
   dst[i] = src[i] ^ d;
   ++d;
}

しかし、ベクトライザーはこれも気に入りませんでした。
ただし、これを行う:

for(int i = 0; i < sz; ++i) {
   dst[i] = src[i] ^ 0x80;
   ++d;
}

正常にベクトル化されましたが、キーが 1 バイトしかないのは、私が望んでいたよりも短くなっています。

ベクトライザーを喜ばせる方法でこのようなことを行う方法はありますか?

4

1 に答える 1

2

これは、Apple (Xcode) の clang で再現できます。モジュロ 64 ブロックを使用すると、ベクトライザーを満たすように見えます。

int i = 0; /* current index. */

int szd = sz / 64;
int szm = sz % 64;
for (int j = 0; j < szd; j++)
{
    for (int k = 0; k < 64; i++, k++)
        dst[i] = src[i] ^ key[k];
}

for (int k = 0; k < szm; i++, k++)
     dst[i] = src[i] ^ key[k];
于 2016-01-18T18:53:46.063 に答える