Ищите функцию, аналогичную _mm256_load_ps, но для указателя на символ - PullRequest
0 голосов
/ 05 июня 2019

По сути, я хочу выполнить маску AND над массивом байтов.Я знаю, что код будет выглядеть примерно так:

char *arr = (char*)_mm_malloc(num_bytes,8);
//fill the array with some values
__m256i mask = _mm256_set1_epi8(0x12);
for(uint32_t i=0; i<num_bytes; i+=32){
    //load for chars is unknown to me
    __m256i val = _mm256_load_char(arr+i);
    val = _mm256_and_si256 (val, mask);
    //perform extra operations with the result
}

Но я не знаю, как безопасно загрузить пакет из 32 байтов в регистр 256.

Ответы [ 2 ]

5 голосов
/ 05 июня 2019

Свойство для vmovdqu ymm, [mem] равно _mm256_loadu_si256( (const __m256i*)any_pointer);

например, _mm256_loadu_si256( (const *__m256i) (arr+i) )

Значение встроенной нагрузки равно _mm256_load_si256();

См. Встроенный искатель Intel https://software.intel.com/sites/landingpage/IntrinsicsGuide/ или другой справочник по встроенным функциям, где вы можете найти подобные вещи.


Если вы выделяете память на месте с помощью _mm_malloc, попросите 32-байтвыравнивание, а не только 8, так что вы можете использовать выравниваемые нагрузки и гарантированно не иметь каких-либо разбиений строки кэша.


Встроенные целочисленные загрузки / хранения Intel имеют глупые прототипы, которые требуют приведения указателя к __m256i* даже если не гарантированно правильно выровнено.Компиляторы, которые реализуют встроенные функции Intel, должны обрабатывать это без какого-либо неопределенного поведения.

(В ISO C ++ даже создание невыровненного указателя без разыменования это UB.)

Встроенные функции загрузки / хранения AVX512, наконец, делают это вменяемым, принимая void*, поэтому вам не нужны все эти шумные / уродливые приведения.

1 голос
/ 05 июня 2019

Есть _mm256_loadu_epi8 (инструкция vmovdqu8), но для этого требуется AVX512.

...