Битовая перестановка множественных 64-битных значений параллельно / комбинированно

Этот вопрос НЕ о "Как сделать битовую перестановку" Мы теперь ищем более быстрый способ с меньшим количеством команд на процессоре, вдохновленный реализацией sboxes в DES

Чтобы ускорить некоторые шифровальные коды, мы хотим уменьшить количество звонков на перестановку. Основные функции шифрования выполняют несколько битовых перестановок, основанных на массивах поиска. Так как операции перестановки - это всего лишь битовые сдвиги,

Наша основная идея состоит в том, чтобы взять несколько входных значений, для которых нужна одна и та же перестановка, и сдвинуть их параллельно. Например, если входной бит 1 должен быть перемещен на выходной бит 6.

Есть ли какой-нибудь способ сделать это? Примерного кода у нас сейчас нет, так как нет абсолютного представления о том, как это сделать производительным способом.

Максимальный размер значений на наших платформах составляет 128 бит, самое длинное входное значение - 64 бита, поэтому код должен быть быстрее, а не делать всю перестановку 128 раз.

EDIT

Вот простой 8-битный пример перестановки

+---+---+---+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <= Bits
+---+---+---+---+---+---+---+---+
+---+---+---+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <= Input
+---+---+---+---+---+---+---+---+
| 3 | 8 | 6 | 2 | 5 | 1 | 4 | 7 | <= Output
+---+---+---+---+---+---+---+---+

Шифр использует несколько клавиш ввода. Это блочный шифр, поэтому один и тот же шаблон должен быть применен ко всем 64-битным блокам входа.

Так как перестановки одинаковы для каждого входного блока, мы хотим обработать несколько входных блоков за один шаг /объединение операций для нескольких входных последовательностей. Вместо того, чтобы перемещать 128 раз по одному биту за вызов, перемещая 1 раз по 128 бит за раз.

EDIT2

Мы НЕ могли использовать потоки, так как нам приходилось запускать код на встроенных системах без поддержки потоков. Поэтому мы также не имеем доступа к внешним библиотекам и вынуждены держать его открытым C.

SOLUTION

После тестирования и проигрывания приведенных ответов мы сделали это следующим образом:

  • Мы помещаем единичные биты 128 64-битных значений в массив uint128_t[64]*.
  • Для перестановки нам осталось только скопировать указатели
  • После всего, что мы сделали, мы возвращаем первую операцию и получаем 128 перепутанных значений обратно

Да, это действительно так просто. Мы тестировали этот способ в самом начале проекта, но он был слишком медленным. Похоже, что у нас была ошибка в тестовом коде.

Спасибо всем за подсказки и терпение.

7
задан Thomas Berger 25 August 2011 в 20:15
поделиться