Использование ЦП в виде простого % не может передать сложность многоядерного, многопоточного, многопроцессорного ЦП и памяти. Почти наверняка Процессор фактически завис в памяти или кеше. И процессы, у которых есть свои данные, будут бороться за исполнительные блоки.
Этот процессор имеет всего 16 ядер. Как вы обнаружили, обращение с ним так, как будто оно имеет 32, в какой-то момент сильно ухудшит производительность. Даже с SMT 2. Возможно, вы можете получить количество потоков до 125% ядер (20), но 175% (28) подталкивают его. Особенно, когда другие вещи запущены. Вернитесь назад.
Обязательно подсчитайте полезную работу, выполняемую потоком в секунду. Экспериментируйте, изменяя одну переменную за раз. Возможно, попробуйте процессоры с разными конфигурациями кеша и количества ядер, если у вас есть к ним доступ.
Измерьте, насколько вы остановились, с помощью счетчиков мониторинга производительности. Не будет работать в виртуальной машине, но стоит попробовать в Linux. От Грегга, на который я ссылался ранее:
perf stat -a -- сон 10
Теоретическая максимальная скорость на Xeon составляет 4 или 5 инструкций за цикл. Вы этого не получите, но < 1.0 IPC дополнительно зависает в памяти.
Определенно получить представление о коде приложения и горячих точках. Какие функции проводят большую часть времени на процессоре? Какой ассемблерный код пострадал больше всего? Какие исполнительные блоки на вашем процессоре работают больше всего, чтобы обработать эти мопы?
Графики пламени хороши для визуализации функций процессора. Вы упомянули EL 8, который упакованный инструментарий Flamegraph.
yum установить perf js-d3-flame-graph
# общесистемный, 99 Гц, в течение 60 секунд
перфорированный скрипт flamegraph -a -F 99 sleep 60
Для полной интерпретации результатов необходимо понимание программы на уровне разработчика. С символами или исходным кодом, отчеты о производительности могут быть аннотированы в отладчике как опыт.