2016-08-09 12 views
0

Проблема

Существует ли инструкция, которая собирает/извлекает первый бит в int[32] и сохраняет его в int?Собирают/Извлечь первый бит из массива Integer

  • Я знаю о внутренней pext, но это не совсем то, что я хочу.

  • У меня есть код для этого, но я подумал, может быть, есть назначенная инструкция.

  • ints массив равен нулю, кроме первого бита. Эрго, не нужно маскировки.

Код

void ints2bits(int &bits, int *ints) { 
    bits = (ints[0] << 0) + (ints[1] << 1) + ... + (ints[31] << 31); 
} 

UPDATE & ОБРАТНОЙ:

Только проверенные предложения Гарольда. Он работает очень хорошо, и я могу добиться хорошей скорости.

+0

Если вы хотите извлечь первый бит из всех 31 целых чисел массива и сохранить бит в соответствующем месте в int, тогда вы ошибаетесь. – sameerkn

+0

Это не ошибка. Я буквально его использую. Вопрос заключается только в том, что для этой операции существует определенная инструкция. Маскирование массива не требуется, кстати, это может быть причина, по которой вы заявляете о своей неисправности. –

+0

Ваш код предполагает, что все остальные биты в int равны нулю, вы должны, вероятно, указать это явно в своей спецификации проблемы. – samgak

ответ

2

Нет единой инструкции, которая может даже считывать столько данных, но группы из 4 (8 с AVX2) могут быть обработаны быстро с использованием _mm_movemask_ps. Игнорируйте тот факт, что он утверждает, что он является инструкцией с плавающей точкой, он просто собирает и добавляет 4 верхних бита.

Конечно, перемещение нижнего долота в верхнюю часть легко с помощью _mm_slli_epi32.

Так положить его вместе (не тестировалось)

int res = 0; 
for (int i = 0; i < 32; i += 4) { 
    __m128i x = _mm_load_si128((__m128i*)&ints[i]); // I assume it's aligned 
    x = _mm_slli_epi32(x, 31); 
    int bits = _mm_movemask_ps(_mm_castsi128_ps(x)); 
    res += bits << i; 
} 

Расширение для AVX2 довольно очевидно.

Другой возможный подход заключается в перемещении каждой полосы на переменную величину (предварительный AVX2 это требует умножения), а затем суммирование, сначала вертикально, конечно, сохранение горизонтальной суммы для последнего. Это, вероятно, медленнее, и, конечно, более неудобно.