Почему strchr в два раза быстрее, чем мой 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

Я не установил флаг оптимизации в компиляторе. Установка -O3 привела к тому, что код SIMD принимал только 75% времени strchr.

Обновление: Я также должен уточнить, что это не окончательная рабочая версия кода. Есть еще дополнительные проверки, которые необходимо ввести в действие, и возможные способы оптимизации вызовов (я думаю). По крайней мере, на данный момент, хотя код находится в шатре strchr. Как указывалось в комментариях к комментариям, эта версия может прочесть страницу и ошибку. Наконец, это, в основном, возможность обучения SIMD (для себя), и memchr - это, вероятно, лучший выбор (хотя я подозреваю, что вы можете слегка бить memchr, если у вас есть буфер-дозор).