Xxhash: 32-битный ARM очень медленный xxhash

Созданный на 2 мар. 2021  ·  4Комментарии  ·  Источник: Cyan4973/xxHash

Скомпилировано с помощью gcc 4.8.5 и протестировано на двухъядерном 32-битном ARM Cortex-A9, все алгоритмы xxhash работают очень медленно и теряют даже реализацию crc32, независимо от размера ввода. Проверено на dev и v0.8.0, разницы не имеет. НЕОНОВАЯ дорожка активирована.

lscpu:
Флаги: half thumb fastmult vfp edsp neon vfpv3 tls vfpd32

Кажется, что эти коды не так протестированы с 32-битной ARM?

question

Самый полезный комментарий

Похоже, что цепочка инструментов неправильно включила оптимизацию компилятора. При их явном включении для сборки xxhashes вычисляются так (быстро, как) должны. Спасибо @ Cyan4973 и @ easyaspi314.

Все 4 Комментарий

Классическая проблема с gcc на 32-битной ARM заключается в том, что
он не использует (по умолчанию) способность ЦП поддерживать невыровненный доступ к памяти
(что, я полагаю, A9 может)
что приводит к очень медленному доступу к памяти.

Здесь можно попробовать несколько вещей.

Со стороны библиотеки предусмотрено несколько методов доступа:
https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h#L1117

Самый агрессивный - XXH_FORCE_MEMORY_ACCESS=2 .
Это может привести к некорректной генерации двоичного файла в зависимости от других настроек и возможностей компилятора.
Но если это сработает, это, по крайней мере, даст представление о том, какой должна быть скорость.

Немного безопаснее, XXH_FORCE_MEMORY_ACCESS=1 сгенерирует правильный код.
Но компилятор должен знать, что процессор может получить доступ к невыровненным адресам памяти.

Для этого может потребоваться указать дополнительный флаг компиляции.
Например, -march=armv7a сообщает gcc что микросхема руки способна получить доступ к невыровненным адресам памяти,
в результате значительно улучшается генерация кода в сочетании с XXH_FORCE_MEMORY_ACCESS=1 .
(К сожалению, согласно Godbolt, этот флаг, связанный со значением по умолчанию XXH_FORCE_MEMORY_ACCESS=0 прежнему обеспечивает плохую производительность в более старой версии gcc . В более новых версиях gcc-6 эта проблема устранена).

Не уверен, что это вариант, но clang также имеет тенденцию генерировать лучший двоичный код для руки.

Наконец, на стороне пользователя
предполагая, что XXH_FORCE_ALIGN_CHECK=1 (https://github.com/Cyan4973/xxHash/blob/dev/xxhash.h#L1179),
обеспечение выровненного ввода (на границах 4 байта для XXH32 )
следует использовать путь кода доступа к памяти с прямым выравниванием.
Это не должно зависеть от компилятора, обнаруживающего возможности невыровненного доступа к памяти,
поскольку доступ к памяти обнаруживается, выровнено с самого начала.

XXH64 , вероятно, будет иметь низкую производительность на 32-битном arm .
Но XXH32 должно быть в порядке.
Более новый XXH3 находится на балансе, базовый уровень должен быть в порядке,
и с поддержкой neon ожидается, что он превзойдет XXH32 по скорости.

_edit_: фиксированное значение доступа к памяти, как подчеркнуто @ easyaspi314

Если я не ошибаюсь, правильные флаги общего назначения для этого процессора будут такими:

-O2   -fomit-frame-pointer -march=armv7-a      -mfpu=neon     -mthumb        -munaligned-access
^duh  ^saves a register    ^sets arch version  ^enables neon  ^use thumb-2   ^force enable unaligned access

Однако, как сказал Янн, я бы также порекомендовал Clang, поскольку он имеет тенденцию генерировать лучший код, особенно с NEON.

Кроме того, вы пробовали более новую версию GCC? Бэкенды GCC ARM и AArch64 довольно посредственные, и до недавнего времени это было довольно плохо.

@ Cyan4973, кстати, XXH_FORCE_MEMORY_ACCESS=3 безопасен, 2 - лукавый.

Похоже, что цепочка инструментов неправильно включила оптимизацию компилятора. При их явном включении для сборки xxhashes вычисляются так (быстро, как) должны. Спасибо @ Cyan4973 и @ easyaspi314.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги