Преобразование из индексов на основе источника в индексы на основе назначений
Я использую инструкции AVX2 в некотором коде C.
Команда VPERMD принимает два 8-целочисленных вектора a
и idx
и генерирует третий, dst
, путем перестановки a
на основе idx
. Это кажется эквивалентным dst[i] = a[idx[i]] for i in 0..7
. Я вызываю этот источник на основе, потому что перемещение индексируется на основе источника.
Однако у меня есть мои расчетные индексы в форме, основанной на адресатах. Это естественно для установки массива и эквивалентно dst[idx[i]] = a[i] for i in 0..7
.
Как я могу конвертировать из исходной формы в форму на основе адреса? Пример тестового примера:
{2 1 0 5 3 4 6 7} source-based form.
{2 1 0 4 5 3 6 7} destination-based equivalent
Для этого преобразования я остаюсь в ymm-регистрах, так что это означает, что решения на основе адресатов не работают. Даже если я должен был вставлять каждый отдельно, поскольку он работает только с постоянными индексами, вы не можете просто установить их.
Ответы
Ответ 1
Я предполагаю, что вы неявно говорите, что не можете изменить свой код для расчета исходных индексов в первую очередь? Я не могу думать ни о чем, что вы можете сделать с x86 SIMD, кроме инструкций рассеяния AVX512, которые принимают индексы на основе dst.
Хранение памяти, инвертирование и перезагрузка вектора могут быть действительно лучшими. (Или перенос в целые регистры напрямую, а не через память, возможно, после vextracti128/packusdw, поэтому вам нужно только две 64-разрядные передачи от вектора к целочисленным regs: movq и pextrq).
Но в любом случае используйте их как индексы для хранения счетчика в массиве в памяти и перезагрузите его как вектор. Это все еще медленное и уродливое, и включает задержку с задержкой в магазине. Поэтому, вероятно, стоит потратить время, чтобы изменить код, генерирующий индекс, для генерации векторов в случайном порядке.