Многопоточное снижение производительности с более новыми версиями g ++? - PullRequest
4 голосов
/ 28 мая 2019

Я написал некоторый код обратного распространения C ++, который я запускаю на i9-9900K в Ubuntu 18.04.

Проблема, с которой я сталкиваюсь, заключается в том, что многопоточная производительность прогрессивно ухудшается с новыми версиями g ++.

Однопоточные тесты улучшаются, как и ожидалось, в новых версиях g ++:

g++ 4.8: 5437 cycles/s
g++ 5.5: 5929 cycles/s
g++ 6.5: 5932 cycles/s
g++ 7.4: 6117 cycles/s
g++ 8.3: 6921 cycles/s

Многопоточные тесты (14 pthreads на 8 ядер) значительно ухудшаются с более новыми версиями:

g++ 4.8: 25456 cycles/s
g++ 5.5: 17212 cycles/s
g++ 6.5: 18616 cycles/s
g++ 7.4: 17054 cycles/s
g++ 8.3: 14797 cycles/s

Я видел подобное поведение и в CentOS 7.6, и в Clear Linux. На всех протестированных ОС самая быстрая производительность достигается благодаря использованию 14 потоков с g ++ 4.8.

Вот флаги компиляции, которые я использую: g ++ -c -std = c ++ 11 -march = native -Ofast

Я использую неправильные флаги для компиляции? Я пробовал -O3, и ухудшение похоже, но менее экстремально (и медленнее, чем -Ofast)

g++ 4.8 -O3: 17256 cycles/s
g++ 5.5 -O3: 15129 cycles/s
g++ 6.5 -O3: 15779 cycles/s
g++ 7.4 -O3: 15736 cycles/s
g++ 8.3 -O3: 13361 cycles/s

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

1 Ответ

1 голос
/ 02 июня 2019

Дальнейшее тестирование показало, что проблема связана с флагом -march = native оптимизации.

g ++ 4.8 изначально обрабатывает i9-9900k как core-avx2, который активирует: MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AES и PCLMUL

G ++ 4.9 и выше относятся к i9-9900k изначально как к широкополосному, который активирует: MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX и PREFETCHW

Очевидно, это как-то приводит к чрезмерной оптимизации.

Удаление флага -march в целом решило проблему.Отключение AVX также работало с использованием -mno-avx и -mno-avx2

...