我正在学习 SIMD,并且很好奇是否有可能在查找字符方面击败 strchr。看起来 strchr 使用相同的内在函数,但我假设它检查空值,而我知道该字符在数组中并计划避免空值检查。
我的代码是:
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
我没有在编译器中设置优化标志。设置 -O3 导致 SIMD 代码仅占用 strchr 时间的 75%。
Update:我还应该澄清这不是代码的最终工作版本。仍然需要进行额外的检查以及优化调用的可能方法(我认为)。至少在这一点上,代码在 strchr 的范围内。正如问题评论中所指出的,此版本可能会读过一页并出现错误。最后,这主要是一个 SIMD 学习机会(对我自己来说),而 memchr 可能是你最好的选择(尽管我怀疑如果你有哨兵缓冲区,你可能能够稍微击败 memchr)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)