SIMD-инструкции загрузка в регистры
Пытаюсь понять, хотя бы на самом примитивном уровне, как работать с SIMD. Нашел вот такую статью: https://woboq.com/blog/utf-8-processing-using-simd.html
Там простой код и пояснение, но я не могу понять:
int fromUtf8(const char *src, int len, unsigned short *dst)
{
//Мы будем обрабатывать ввод по 16 байт за раз, поэтому длина должна быть не менее 16.
while(len >= 16)
{
//Загрузить 128 бит в векторный регистр. Мы используем встроенный 'loadu', где «u» означает не выровненный. Загрузка выровненных данных намного быстрее, но здесь мы не знаем, выровнен ли источник.
__m128i chunk = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src));
//Определить, является ли это ASCII, проверив, установлен ли старший бит одного байта:
if (!_mm_movemask_epi8(chunk))
{
//....
}
}
В этом коде я не могу понять - авто статьи пишет, что функция fromUtf8 принимает указатель на char* в котором находится 16 бит или 2 байта.
Но теперь авто статьи использует SIMD-функцию _mm_loadu_si128, которая загружает в регистры 128 бит или 16 байтов - по указанному источнику src, но ведь длинна src всего 2 байта.
Разве так можно делать ? Разве _mm_loadu_si128 не загрузит в регистры мусор, который будет после 2 байта в источнике src ?
Ответы (1 шт):
Я не читал статью, но тут предельно ясно:
- Есть указатель на массив символов (источник), и в нем вовсе не 16 бит.
- Дальше имя
__m128i chunkсразу подсказывает намерение встроенногоloadu: обрабатывает по кускам символьную строку по 128 бит( по 16 символов UTF-8), потому передаетсяreinterpret_cast<const __m128i*>(src). - И, чтобы это было в пределах источника, выполняется в цикле
while(len >= 16), и потому _mm_loadu_si128 не загрузит в регистры мусор. - Но, с чего вы взяли, что длина
srcвсего байта, я не знаю...