Я пытаюсь ускорить побитовую операцию ИЛИ для очень длинных двоичных векторов, используя 32-битные целые числа.
В этом примере мы можем предположить, что nwords — это количество слов, кратное 4 и 8. Следовательно, нет напоминания о цикле. Этот двоичный вектор может содержать многие тысячи битов.
Более того, все три битовых вектора выделяются с помощью _align_malloc() с выравниванием по 16 и 18 битам для SSE2 и AVX2 соответственно.
К моему удивлению, следующие три скалярных кода, кода SSE2 и AVX2 выполнялись с одинаковым количеством времени на моем процессоре i7. Я не испытал ожидаемого ускорения x4 и x8 для регистров SSE2 и AVX2.
Моя версия MVisual Studio 15.1.
Скалярный код:
void vectorOr_Scalar(unsigned int *ptr1, unsigned int *ptr2, unsigned int *out, int nwords)
{
for (end = ptr1 + nwords; ptr1 < end; ptr1++, ptr2++, out++) *out = *ptr1 | *ptr2;
}
Код SSE2:
void vectorOr_SSE2(unsigned int *ptr1, unsigned int *ptr2, unsigned int *out, int nwords)
{
for (i = 0; i < nwords; i += 4, ptr1 += 4, ptr2 += 4, out += 4)
{
__m128i v1 = _mm_load_si128((__m128i *)ptr1);
__m128i v2 = _mm_load_si128((__m128i *)ptr2);
_mm_store_si128((__m128i *)out, _mm_or_si128(v1, v2));
}
}
Код AVX2:
void vectorOr_AVX2(unsigned int *ptr1, unsigned int *ptr2, unsigned int *out, int nwords)
{
for (i = 0; i < nwords; i += 8, ptr1 += 8, ptr2 += 8, out += 8)
{
__m256i v1 = _mm256_load_si256((__m256i *)ptr1);
__m256i v2 = _mm256_load_si256((__m256i *)ptr2);
_mm256_store_si256((__m256i *)out, _mm256_or_si256(v1, v2));
}
}
Возможно, это приложение не подходит для векторизации из-за ограниченного количества операций с регистрами между загрузкой и сохранением?
#pragma omp parallel for simd
- person Victor Gubin   schedule 13.11.2019vorps
илиvpor
в горячем цикле: godbolt.org/z/MR2x8V - person chtz   schedule 13.11.2019