我试图至少在最原始的层面上理解如何使用 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))
{
//....
}
}
在这段代码中,我无法理解 - auto 文章写道,fromUtf8 函数需要一个指向 char * 的指针,其中有 16 位或 2 个字节。
但是现在文章 auto 使用了 _mm_loadu_si128 SIMD 函数,它将 128 位或 16 字节加载到寄存器中 - 根据指定的 src 源,但 src 只有 2 个字节长。
有可能这样做吗?_mm_loadu_si128 不会将垃圾加载到寄存器中,这将在 src 源中的 2 个字节之后?
这篇文章我没看过,但是这里很清楚:
__m128i chunk
直接暗示了内置的意图loadu
:它处理一个 128 位的字符串片段(每个 16 个 UTF-8 字符),因此reinterpret_cast<const __m128i*>(src)
.while(len >= 16)
,因此 _mm_loadu_si128 不会将垃圾加载到寄存器中。src
整个字节的长度,我不知道......