У меня есть массив массивов с плавающей точкой (~ 20 cols x ~ 1M строк), из которых мне нужно извлечь два столбца за раз в два регистра __m256
.
...a0.........b0......
...a1.........b1......
// ...
...a7.........b7......
// end first __m256
Наивный способ сделать это -
__m256i vindex = _mm256_setr_epi32(
0,
1 * stride,
2 * stride,
// ...
7 * stride);
__m256 colA = _mm256_i32gather_ps(baseAddrColA, vindex, sizeof(float));
__m256 colB = _mm256_i32gather_ps(baseAddrColB, vindex, sizeof(float));
Однако мне было интересно узнать, могу ли я получить более высокую производительность, извлекая a0, b0, a1, b1, a2, b2, a3, b3
в один gather
и a4, b4, ... a7, b7
в другой, потому что они ближе в памяти, а затем де-чередуют их. То есть:
// __m256 lo = a0 b0 a1 b1 a2 b2 a3 b3 // load proximal elements
// __m256 hi = a4 b4 a5 b5 a6 b6 a7 b7
// __m256 colA = a0 a1 a2 a3 a4 a5 a6 a7 // goal
// __m256 colB = b0 b1 b2 b3 b4 b5 b6 b7
Я не могу понять, как красиво перемежать lo
и hi
. Мне в основном нужна противоположность _mm256_unpacklo_ps
. Самое лучшее, что я придумал, это что-то вроде:
__m256i idxA = _mm256_setr_epi32(0, 2, 4, 6, 1, 3, 5, 7);
__m256i idxB = _mm256_setr_epi32(1, 3, 5, 7, 0, 2, 4, 6);
__m256 permLA = _mm256_permutevar8x32_ps(lo, idxA); // a0 a1 a2 a3 b0 b1 b2 b3
__m256 permHB = _mm256_permutevar8x32_ps(hi, idxB); // b4 b5 b6 b7 a4 a5 a6 a7
__m256 colA = _mm256_blend_ps(permLA, permHB, 0b11110000); // a0 a1 a2 a3 a4 a5 a6 a7
__m256 colB = _mm256_setr_m128(
_mm256_extractf128_ps(permLA, 1),
_mm256_castps256_ps128(permHB)); // b0 b1 b2 b3 b4 b5 b6 b7
Это 13 циклов. Есть ли лучший способ?
(Насколько мне известно, prefetch уже оптимизирует наивный подход как можно лучше, но, не имея этих знаний, я надеялся сравнить второй подход. Если кто-то уже знает, каков будет результат этого, пожалуйста, разделите. С помощью вышеупомянутого метода деинтерлейсинга он примерно на 8% медленнее, чем наивный подход.)
Изменить Даже без деинтерлейсинга метод "проксимального" сбора примерно на 6% медленнее, чем метод наивного метода постоянной шага. Я полагаю, что это означает, что этот шаблон доступа слишком сильно запутывает предварительную выборку оборудования, чтобы быть полезной оптимизацией.