LINUX.ORG.RU

Опция -threaded в haskell

 


0

2

Вопрос касается кода, скомпилированного с помощью -O2 -threaded и запущенного с помощью +RTS -N.

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

Тут понадобилась опция -threaded. И что я вижу: на алгоритмически однопоточном коде на процессоре Intel с двумя ядрами и гипертредингом нагрузка под 70% (от максимальной 100%) при использовании опций запуска +RTS -N. А потоков создается не меньше десяти! Как будто загружены 3 ядра из 4-х. Меня это удивило, мягко говоря. Подозреваю, что black holes имеют определенную стоимость в многопоточном коде, как и RTS.

Если взять тот же самый код, но без -threaded, то он отрабатывает на доли процента быстрее, с загрузкой всего 1 ядра и с 2-я потоками в окне Мониторинга Системы, где активным, скорее всего, является всего один поток.

Есть какие-нибудь оценки по этому поводу? На сколько ядер нужно рассчитывать про запас, чтобы, скажем запустить код с 4-я активными потоками, или с 8-ю?

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

★★★★★

Последнее исправление: dave (всего исправлений: 2)

Показывает ли threadscope чем занимается -threaded программа вместо того, чтобы грузить CPU? '+RTS -sstderr' должен показать где затык: в GC или сгенеренном коде (MUT time).

На большом количестве ядер помогает тюнить распределитель памяти (в новых версиях GHC дефолты получше): http://trofi.github.io/posts/193-scaling-ghc-make.html

В threaded runtime black holes являются более тяжеловесными. Вместо мгновенного переключения потока они тратят несколько итераций перед тем, как переключиться на следующий haskell thread. Но это приводит к повышению нагрузки на CPU (без полезного выхлопа), а не снижению.

Если black holes являются точками сериализации всех потоков - значит программа плохо параллелится и нужно убирать глобальные MVars, unsafePerformIO (и другие реализации мьютексов).

sf ★★★
()
Ответ на: комментарий от sf

Ну, у меня GC сильно напрягается. Это известно заранее. Создается очень много кратко-живущих объектов. Статистика по -sstderr это подтверждает.

Вопрос скорее был, а это норма, что вместо одного ядра загружено сразу три?

Код по факту однопоточный. Никаких MVars и unsafePerformIO. Приписываю лишнюю нагрузку на ядра системе RTS.

threadscope еще не запускал для этого теста, но программа установлена. Пожалуй, стоит проверить

dave ★★★★★
() автор топика
Ответ на: комментарий от sf

Спасибо, про threadscope я что-то и забыл совсем

dave ★★★★★
() автор топика
Ответ на: комментарий от dave

Вопрос скорее был, а это норма, что вместо одного ядра загружено сразу три?

Да, если много мусора, то параллельный GC (по умолчанию gen1) собирает мусор параллельно на всех головах (+RTS -qn<n> можно покрутить)

sf ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.