Я хочу написать функцию параллельного отображения на Haskell, которая будет максимально эффективной. Моя первоначальная попытка, которая в настоящее время кажется лучшей, состоит в том, чтобы просто написать:
pmap :: (a -> b) -> [a] -> [b]
pmap f = runEval . parList rseq . map f
Однако я не вижу идеального разделения ЦП. Если это, возможно, связано с количеством искр, могу ли я написать pmap, который делит список на # сегментов процессора , чтобы образовалось минимальное количество искр? Я пробовал следующее, но производительность (и количество искр) намного хуже
pmap :: (a -> b) -> [a] -> [b]
pmap f xs = concat $ runEval $ parList rseq $ map (map f) (chunk xs) where
-- the (len / 4) argument represents the size of the sublists
chunk xs = chunk' ((length xs) `div` 4) xs
chunk' n xs | length xs <= n = [xs]
| otherwise = take n xs : chunk (drop n xs)
. Более низкая производительность может быть связана с более высоким использованием памяти. Исходный pmap в некоторой степени масштабируется в 24-ядерных системах, поэтому дело не в том, что у меня недостаточно данных. (Количество процессоров на моем рабочем столе - 4, поэтому я просто жестко запрограммировал это.)
Некоторые данные о производительности с использованием + RTS -H512m -N -sstderr -RTS
находятся здесь: