我正在学习SIMD,很想知道是否有可能在找到角色时击败strchr。似乎strchr使用相同的内在函数但我假设它检查null,而我知道该字符在数组中并且计划避免空检查。
我的代码是:
size_t N = 1e9;
bool found = false; //Not really used ...
size_t char_index1 = 0;
size_t char_index2 = 0;
char * str = malloc(N);
memset(str,'a',N);
__m256i char_match;
__m256i str_simd;
__m256i result;
__m256i* pSrc1;
int simd_mask;
str[(size_t)5e8] = 'b';
char_match = _mm256_set1_epi8('b');
result = _mm256_set1_epi32(0);
simd_mask = 0;
pSrc1 = (__m256i *)str;
while (1){
str_simd = _mm256_lddqu_si256(pSrc1);
result = _mm256_cmpeq_epi8(str_simd, char_match);
simd_mask = _mm256_movemask_epi8(result);
if (simd_mask != 0){
break;
}
pSrc1++;
}
完整(尚未完成的代码): https://gist.github.com/JimHokanson/433e185ba53b41e49ce3ac804568ac1e
strchr的速度是此代码的两倍(使用gcc和xcode)。我希望了解原因。
更新:使用编译:gcc -std = c11 -mavx2 -mlzcnt
答案 0 :(得分:0)
我没有在编译器中设置优化标志。设置-O3导致SIMD代码仅占用strchr的75%的时间。
更新:我还应该澄清这不是代码的最终工作版本。还需要进行额外的检查以及优化呼叫的可能方式(我认为)。至少在这一点上虽然代码是strchr的球场。正如问题评论中指出的那样,这个版本可以读取过去的页面和错误。最后,这主要是一个SIMD学习机会(对我自己而言),memchr可能是你最好的选择(虽然我怀疑如果你有一个哨兵缓冲区,你可能会略微击败memchr。)