Загрузить вектор в регистр AVX2 с несоответствующим размером - PullRequest
1 голос
/ 01 марта 2020

Предположим, у меня есть вектор двойных чисел C ++, который должен быть загружен в регистр AVX2. Это можно просто сделать с помощью команды _mm256_load_pd(&vector1[0]).
Вектор может иметь любой размер и не должен быть кратным 4. Какой теперь самый эффективный и эффективный способ загрузки оставшихся векторных элементов, если размер вектора не кратен 4?

Ответы [ 3 ]

3 голосов
/ 01 марта 2020

Дополняет ваш массив делением на четыре, что приводит к пустой трате памяти, но устраняет неэффективность операторов if и ветвления.

2 голосов
/ 02 марта 2020

Если вы хотите загрузить элементы для выполнения поэлементных операций (и впоследствии сохранить их для того же или другого вектора), простое решение - использовать перекрывающиеся нагрузки / хранилища.

Упрощенный пример ( требуется специальная обработка, если vect.size()<4)

// load last four elements for later use
__m256d last_input = _mm256_loadu_pd(vect.data()+vect.size()-4);
for(size_t i=0; i<vect.size()-4; i+=4) { // main loop
  __m256d input = _mm256_loadu_pd(vect.data()+i);
  _mm256_storeu_pd(some_operation(input), output.data()+i);
}
// process and store last elements (possibly overlapping with previous store):
_mm256_storeu_pd(some_operation(last_input, output.data()+vect.size()-4);

Убедитесь, что компилируется с оптимизацией, а в gcc / clang с -march=native (в противном случае невыровненные загрузки / хранилища могут быть неэффективно разделены).

2 голосов
/ 01 марта 2020

Вы можете использовать инструкцию _mm256_maskload_pd. Требуется второй параметр, чтобы указать, какие значения загрузить.

...