2016-09-02 8 views
2

В соответствии с bit twiddling hacks веб-сайт, операцииОбъединить бит последовательности А и В в соответствии с маской

unsigned int a; // value to merge in non-masked bits 
unsigned int b; // value to merge in masked bits 
unsigned int mask; // 1 where bits from b should be selected; 0 where from a. 
unsigned int r; // result of (a & ~mask) | (b & mask) goes here 

r = a^((a^b) & mask); 

позволяет объединить два битовых последовательностей a и b в соответствии с маской. Мне было интересно:

  1. Имеет ли эта операция конкретное/обычное название?
  2. Существует ли конкретная инструкция по сборке для этой операции на каком-либо наборе команд?
+2

* «Имеет ли конкретная инструкция по сборке для этой операции на каком-либо наборе команд?» * - Я не знал бы какого-либо набора команд, который ** не выполнял ** операции AND и XOR. – IInspectable

+0

Но, возможно, некоторые архитектуры имеют эту операцию, подключенную к аппаратным средствам, чтобы сделать это в одной команде вместо нескольких. – Vincent

+2

Это довольно стандартный расчет для [Ternary Raster Operations] (https://msdn.microsoft.com/en-us/library/dd145130.aspx), так что да, я бы предположил, что выделенная схема доступна. – IInspectable

ответ

2

В программировании SSE/AVX, избирательное копирование с одного вектора на другой на основе маски называется смесь. В SSE4.1 добавлены инструкции, такие как PBLENDVB xmm1, xmm2/m128, <XMM0>, где неявный операнд XMM0 контролирует, какие байты src перезаписывают соответствующие байты в dst. (Без SSE4.1 вы обычно должны И и ANDNOT маску на два вектора, а OR - вместе, трюк xor имеет меньше параллелизма на уровне инструкций и, вероятно, требует, чтобы по меньшей мере столько команд MOV копировали регистры.)

Существует также инструкция немедленного смешивания, pblendw, где маска является 8-битным немедленным, а не регистром. И есть 32-битные и 64-битные немедленные смеси (blendps, blendpd, vpblendd) и переменные смеси (blendvps, blendvpd).

IDK, если другие наборы инструкций SIMD (NEON, AltiVec, любые MIPS называет их и т. Д.) Также называют их «смесями» или нет.


SSE/AVX (или x86 целочисленные инструкции) не дают ничего лучше, чем обычный побитовое исключающее ИЛИ/И для этого побитовое (вместо поэлементно) не смешивается до AVX512F.

AVX512F может сделать версию побитовое этого (или любой другой побитовое трехкомпонентную функция) с одним или vpternlogdvpternlogq инструкции. (Единственное различие между размерами элементов d и q заключается в том, что вы используете регистр маски для маскирования слияния или нулевой маскировки адресата, но это не помешало Intel делать отдельные функции даже для случая без маски:

__m512i _mm512_ternarylogic_epi32 (__m512i a, __m512i b, __m512i c, int imm8) и эквивалент ..._ epi64 версия.

imm8 немедленных байт является таблицей истинности. Каждый битого назначения определяется независимо, из соответствующих бит а, б и в с использованием их в качестве 3- разрядный индекс в таблицу истинности, т. е. как imm8[a:b:c].

AVX512 будет забавно играть, когда он в конце концов появится в главном рабочем столе/ноутбуке CPU, но это, вероятно, еще пару лет.

+0

Я не понимаю, почему xor трюк не работает для векторов? Да, вам нужно развернуть маску того же размера, что и смещенные векторы, но это верно и для решения AND + ANDN + OR? В любом случае, xor сохраняет только один «не» по сравнению с обычным подходом, поэтому, если у вас есть ANDN, преимущество исчезает (поскольку он не складывается в и). – BeeOnRope

+0

@BeeOnRope: '(a^b)' побитово внутри элементов, что не является тем, что вы хотите для сочетания элементов-гранулярности. Или все это отменяется в конце? На самом деле я не очень сильно разбирался в методе xor! –

+1

Да, но я имею в виду раздел «без SSE 4.1», в котором вы сказали, что обычным способом было использование ANDN, потому что xor трюк не применяется. Метод xor работает с тем же типом маски, что и подход AND (да, оба являются битными гранулами). Так что да, если у вас есть 16-битная маска и что использовать ее для управления 128-битной смесью элементов байта, вам нужно развернуть каждый бит в маске до полного байта (0 или 255), но это верно как для обоих подходы. Xor трюк, похоже, применим здесь (но в галстуке, а не в выигрыше, поскольку существует ANDN). – BeeOnRope