Как вставить нули между битами в растровое изображение?

У меня есть тяжелый по производительности код, который выполняет битовые манипуляции. Это может быть сведено к следующей четко определенной проблеме:

Для 13-битной битовой карты построить 26-битную битовую карту, которая содержит исходные биты, разнесенные на четные позиции .

Для иллюстрации:

0000000000000000000abcdefghijklm (input, 32 bits)
0000000a0b0c0d0e0f0g0h0i0j0k0l0m (output, 32 bits)

В настоящее время у меня это реализовано на C следующим образом:

if (input & (1 << 12))
    output |= 1 << 24;
if (input & (1 << 11))
    output |= 1 << 22;
if (input & (1 << 10))
    output |= 1 << 20;
...

Мой компилятор (MS Visual Studio) превратил это в следующее:

test        eax,1000h
jne         0064F5EC
or          edx,1000000h
... (repeated 13 times with minor differences in constants)

Интересно, смогу ли я сделать это быстрее. Я хотел бы, чтобы мой код был написан на C, но возможно переключение на язык ассемблера.

  • Могу ли я использовать некоторые инструкции MMX / SSE для одновременной обработки всех битов?
  • Может быть, я могу использовать умножение? (умножьте на 0x11111111 или другую магическую константу)
  • Было бы лучше использовать инструкцию установки условий (SETcc) вместо инструкции условного перехода? Если да, как я могу заставить компилятор генерировать такой код для меня?
  • Есть ли еще идеи, как сделать это быстрее?
  • Есть идеи, как сделать обратное преобразование растрового изображения (я тоже должен его реализовать, но это менее важно)?
11
задан anatolyg 4 January 2011 в 20:11
поделиться