Индексы ненулевых байтов регистра SSE / AVX
Если значение регистра SSE / AVX таково, что все его байты равны 0 или 1, есть ли способ эффективно получить индексы всех ненулевых элементов?
Например, если значение xmm равно | r0 = 0 | r1 = 1 | r2 = 0 | r3 = 1 | r4 = 0 | r5 = 1 | r6 = 0 | ... | r14 = 0 | r15 = 1 | результат должен быть что-то вроде (1, 3, 5, ..., 15). Результат должен быть помещен в другую переменную _m128i или массив char [16].
Если это помогает, мы можем предположить, что значение регистра таково, что все байты равны 0 или некоторому постоянному ненулевому значению (необязательно 1).
Мне очень интересно, есть ли инструкция для этого или, предпочтительно, C / C ++ встроенная. В любом SSE или AVX набор инструкций.
РЕДАКТИРОВАТЬ 1:
Это было правильнонаблюдается @ zx485 этот оригинальный вопрос не был достаточно ясен. Я искал какое-нибудь «последовательное» решение.
Пример0 1 0 1 0 1 0 1...
выше должно привести к одному из следующих:
0
будет завершающим байтом, и результат может быть002 004 006 008 010 012 014 016 000 000 000 000 000 000 000 000
Если мы предположим, что отрицательный байт является завершающим байтом, результат может быть001 003 005 007 009 011 013 015 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
Все, что дает в качестве последовательных байтов, которые мы можем интерпретировать как индексы ненулевых элементов в исходном значенииРЕДАКТИРОВАТЬ 2:
Действительно, как@Гарольд а также@ Питер Кордес предложить в комментариях к исходному сообщению одно из возможных решений - сначала создать маску (например, с помощьюpmovmskb
) и проверьте ненулевые индексы там. Но это приведет к петле.