为什么strchr的速度是我的simd代码的两倍

时间:2017-11-12 05:25:43

标签: c simd

我正在学习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

1 个答案:

答案 0 :(得分:0)

我没有在编译器中设置优化标志。设置-O3导致SIMD代码仅占用strchr的75%的时间。

更新:我还应该澄清这不是代码的最终工作版本。还需要进行额外的检查以及优化呼叫的可能方式(我认为)。至少在这一点上虽然代码是strchr的球场。正如问题评论中指出的那样,这个版本可以读取过去的页面和错误。最后,这主要是一个SIMD学习机会(对我自己而言),memchr可能是你最好的选择(虽然我怀疑如果你有一个哨兵缓冲区,你可能会略微击败memchr。)