Эффективно вычислить сумму битов с помощью SSE - PullRequest
0 голосов
/ 23 октября 2018

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

Я пытаюсь суммировать N битов bit[0], ..., bit[N-1] и записать результат в двоичном виде в вектор result[0], ..., result[bits_N-1], где bits_N - количество бит, необходимое для записи N в двоичном виде.Эта сумма выполняется побитно: каждый bit[i] является длинным целым без знака, и в его j-й бит сохраняется 0 или 1. В результате я делаю 64 суммы, каждый из N бит, впараллельно.

В строках 80-105 я делаю эту сумму, используя 64-битную арифметику.

В строках 107-134 я делаю это с помощью SSE: я сохраняю первую половину суммы bit[0], ...., bit[N/2-1] в первых 64 битах объектов _m128i BIT[0], ..., BIT[N/2-1] соответственно.Аналогично, я сохраняю bit[N/2], ...., bit[N-1] в последних 64 битах BIT[0], ..., BIT[N/2-1], соответственно, и суммирую все BIT s.Пока все работает нормально, и 128-битная сумма занимает столько же времени, сколько и 64-битная.Однако, чтобы получить окончательный результат, мне нужно сложить две половинки друг с другом, см. Строки 125-132.Это занимает много времени и заставляет меня терять усиление, полученное с помощью SSE.

Я использую это на процессоре Intel® i7-4980HQ @ 2.80GHz с gcc 7.2.0.

Знаете ли вы способ обойти это?

1 Ответ

0 голосов
/ 23 октября 2018

Нижняя часть может быть тривиально сохранена с помощью инструкции movq или либо _mm_storel_epi64 (__m128i* mem_addr, __m128i a); внутреннего хранения в памяти, либо _mm_cvtsi128_si64 сохранения для регистрации.

Существует также копия _mm_storeh_pd, которая требуетприведение к pd и может вызвать остановку из-за смешивания чисел с плавающей запятой и целых чисел.

Верхняя часть, конечно, может быть перемещена в нижнюю часть с помощью _mm_shuffle_epi(src, 0x4e), а затем сохранена с помощью movq.

...