Вопрос о эффективном параллелизме, который задает новичок Haskell.Укрощение параллелизма в Haskell/GHC
Задача Advent of Code Day 14 связана с созданием хэшей MD5 последовательности целых чисел, ищем первые n целых чисел, которые дают хеши, выполняющие определенные свойства. Я делаю это по существу, создавая хеши, затем фильтруя их.
Я думал, что было бы хорошо попробовать параллелизм, используя несколько ядер для генерации хэшей.
непараллельная версия создания хеша выглядит следующим образом:
md5sequenceS :: [String]
md5sequenceS = [makeMd5 i | i <- [0..]]
where makeMd5 i = stretch $ getHash (salt ++ show i)
stretch h0 = foldr (\_ h -> getHash h) h0 [1..2016]
... и она отлично работает, хотя и медленно, давая ответ примерно через четыре минуты.
Параллельная версия выглядит следующим образом:
md5sequenceS :: [String]
md5sequenceS = parMap rdeepseq (makeMd5) [0..]
where makeMd5 i = stretch $ getHash (salt ++ show i)
stretch h0 = foldr (\_ h -> getHash h) h0 [1..2016]
... то же самое, как и раньше помимо parMap rdeepseq
бит. Это не работает нормально: он потребляет всю доступную память на моей машине и по-прежнему не дает ответа через 30 минут времени на стене. Тем не менее, он использует все процессоры полностью.
Что я должен сделать, чтобы укротить этот параллелизм вне контроля?
(Проблема спецификации не дает никакого понятия о том, как много хэшей мне нужно генерировать, но оказывается, что мне нужно около 30 000 целых хэшируются.)
Редактировать включить принято отвечать
стратегия parBuffer
может быть использована в качестве
md5sequenceS = withStrategy (parBuffer 100 rdeepseq) $ map (makeMd5) [0..]
where makeMd5 i = stretch $ getHash (salt ++ show i)
stretch h0 = foldr (\_ h -> getHash h) h0 [1..2016]
производительности не велика по сравнению с однопоточной версией, но это другой вопрос ...
Это объяснило бы это, спасибо! Перезапись параллельной версии как 'md5sequenceS = withStrategy (parBuffer 100 rdeepseq) $ map (makeMd5) [0 ..]' делает трюк. Настенное время теперь 3мин 44 с с 12 ядрами, против 5 минут 55 секунд для однопроцессорной версии, но это еще одна проблема ... –