Вопрос

Я ищу самый быстрый способ поставить на большой буфер 512 или более байтов. Я могу гарантировать любую необходимое выравнивание, и размер буфера всегда является мощностью 2. Буфер соответствует блокирующим распределениям, поэтому, как правило, биты либо все набора, None Set, либо в основном устанавливают, что поддерживают «левый» буфера, с случайные дыры.

Некоторые решения, которые я рассмотрел:

Я заинтересован в быстром решении, он должен работать на чипсетах 32 битного X86, принадлежащего CORE2 или более свежу. SSE и SIMD представляют большой интерес. Я буду тестировать на следующий четырехъядерный CPU:

matt@stanley:~/anacrolix/public/stackoverflow$ cat /proc/cpuinfo 
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 15
model name      : Intel(R) Core(TM)2 Quad CPU    Q6600  @ 2.40GHz
stepping        : 11
cpu MHz         : 1600.000
cache size      : 4096 KB
physical id     : 0
siblings        : 4
core id         : 0
cpu cores       : 4
apicid          : 0
initial apicid  : 0
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 10
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc arch_perfmon pebs bts aperfmperf pni dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm lahf_lm tpr_shadow vnmi flexpriority
bogomips        : 4800.21
clflush size    : 64
cache_alignment : 64
address sizes   : 36 bits physical, 48 bits virtual
power management:
Это было полезно?

Решение 3

Я описываю лучшие функции C / Absle, которые я нашел для Количество популяций / вес Hamming больших буферов ниже.

Самая быстрая функция сборки ssse3_popcount3, описано здесь. Отказ Это требует Ssse3., доступно на Intel Core 2 и более поздних, а чипсеты AMD, прибывающие в 2011 году. Он использует Камин Инструкции по просвечиванию в 16 байтовых кусках и разворачиваются 4 петлевых итерациями одновременно.

Самая быстрая функция C popcount_24words, описано здесь. Отказ Он использует алгоритм битового нарезка. Обратите внимание, что я обнаружил, что замыкание Может фактически генерировать соответствующие инструкции по сборке вектора, которые дали впечатляющие результаты повышения производительности. Это в сторону, алгоритм все еще очень быстрый.

Другие советы

Увидеть 32-битную версию в Руководство по оптимизации программного обеспечения AMD, стр. 195 для одной реализации. Это дает вам код сборки для X86 напрямую.

Увидеть вариант в Стэнфорд бит-Twiddling HacksСтэнфордская версия выглядит лучшего для меня. Это выглядит очень легко кода как x86 ASM.

Ни один из этих использует филиал инструкции.

Они могут быть обобщены до 64-битных версий.

С 32 или 64-битной версиями вы можете рассмотреть возможность выполнения версии SIMD. SSE2 выполнит 4 двойных слова или два квадрабра (в любом случае 128 бит) сразу. То, что вы хотите сделать, это реализовать попку на 32 или 64 бита в каждом из 2 или 4 регистров. Вы в конечном итоге с 2 или 4 наборами попкуссов в регистрах XMM, когда вы закончите; Последний шаг - хранить и добавить эти попкусы вместе, чтобы получить окончательный ответ. Угадай, я ожидаю, что вы сделаете это немного лучше, делая 4 параллельных 32-битных попкуса, а не 2 параллельных 64-битных попкусанта, так как последнее, вероятно, потребуется 1 или 2 дополнительных инструкции в каждой итерации, и его легко добавить 4, 32 бит ценности вместе конец.

Я бы предложил реализовать одну из оптимизированных 32-битных процедур POPCNT от Восхищение хакера, но сделайте это для 4 х 32 битных целочисленных элементов в векторе SSE. Затем вы можете обрабатывать 128 бит на итерацию, что должно дать вам около 4X пропускной способности по сравнению с оптимизированной 32-битной скалярной рутиной.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top