Если у вас есть входной массив и выходной массив, но вы хотите только написать те элементы, которые передают определенное условие, что было бы самым эффективным способом сделать это в AVX2?
Я видел в SSE, где это было сделано следующим образом: (От: https://deplinenoise.files.wordpress.com/2015/03/gdc2015_afredriksson_simd.pdf)
__m128i LeftPack_SSSE3(__m128 mask, __m128 val)
{
// Move 4 sign bits of mask to 4-bit integer value.
int mask = _mm_movemask_ps(mask);
// Select shuffle control data
__m128i shuf_ctrl = _mm_load_si128(&shufmasks[mask]);
// Permute to move valid values to front of SIMD register
__m128i packed = _mm_shuffle_epi8(_mm_castps_si128(val), shuf_ctrl);
return packed;
}
Это кажется прекрасным для SSE, который имеет ширину 4 и, следовательно, ему нужен только 16-разрядный LUT, но для AVX, ширина которого 8, LUT становится довольно большим (256 записей, каждый 32 байта или 8 тыс.).
Я удивлен, что у AVX нет инструкции для упрощения этого процесса, например, в масках с упаковкой.
Я думаю, что, немного перепутав, чтобы подсчитать количество знаковых битов, установленных слева, вы можете сгенерировать необходимую таблицу перестановок, а затем вызвать _mm256_permutevar8x32_ps. Но это также немало инструкций, которые я думаю.
Кто-нибудь знает какие-либо трюки, чтобы сделать это с помощью AVX2? Или что является наиболее эффективным методом?
Вот иллюстрация проблемы левой упаковки из приведенного выше документа:
Спасибо