SSE を使用して文字列を反転するにはどうすればよいですか? この概念は私にとって新しいので、それについての情報を教えてください。その理由は、SSE を使用するとコードと実行時間が短縮されると誰かが言っているからです。
_mm128 である SSE を検索しましたが、因数分解する方法がよくわかりません。
ありがとうございました
最低限の SSSE3 を想定できる場合、 を使用するのは非常に簡単_mm_shuffle_epi8
ですが、これを行う前に、(a) 現在の実装がパフォーマンスのボトルネックであること、および (b) 現在の実装を行うためにできる限りのことを行ったことを確認する必要があります。これは非常に単純な操作であるため、適切な実装の場合、そのパフォーマンスは実際にはメモリ帯域幅によってのみ制限されるはずです。
とにかく、ここに簡単な実装とテスト ハーネスがあります。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tmmintrin.h> // SSSE3
void reverse(char *begin, char *end)
{
while (begin < end)
{
const char c = *begin;
*begin = *end;
*end = c;
++begin;
--end;
}
}
void vreverse(char *begin, char *end)
{
const __m128i vrev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
ssize_t len = end - begin + 1;
while (len >= 16)
{
__m128i v1 = _mm_loadu_si128((__m128i *)begin);
__m128i v2 = _mm_loadu_si128((__m128i *)(end - 15));
v1 = _mm_shuffle_epi8(v1, vrev);
v2 = _mm_shuffle_epi8(v2, vrev);
_mm_storeu_si128((__m128i *)(end - 15), v1);
_mm_storeu_si128((__m128i *)begin, v2);
begin += 16;
end -= 16;
len -= 32;
}
if (len > 1)
{
reverse(begin, end);
}
}
int main(void)
{
const size_t MAX_LEN = 64;
char s1[MAX_LEN + 1], s2[MAX_LEN + 1];
size_t i, len;
for (len = 0; len < MAX_LEN; ++len)
{
for (i = 0; i < len; ++i)
{
s1[i] = s2[i] = (char)('a' + rand() % 26);
}
s1[len] = s2[len] = '\0';
reverse(s1, s1 + len - 1);
vreverse(s2, s2 + len - 1);
if (memcmp(s1, s2, len) != 0)
{
printf("FAIL: len = %zu\n", len);
printf("FAIL: s1 = %s\n", s1);
printf("FAIL: s2 = %s\n", s2);
}
else
{
//printf("PASS: len = %zu\n", len);
}
}
return 0;
}
試して:
$ gcc -Wall -mssse3 -O3 vreverse.c && ./a.out
$