Я хочу написать функцию параллельной карты в Haskell как можно более эффективную. Моя первоначальная попытка, которая, кажется, в настоящее время лучше всего, состоит в том, чтобы просто написать,
pmap :: (a -> b) -> [a] -> [b]
pmap f = runEval . parList rseq . map f
Тем не менее, я не вижу идеального разделения процессоров. Если это возможно связано с количеством искр, могу ли я написать pmap, который делит список на # сегментов cpus, так что создаются минимальные искры? Я попробовал следующее, но показатель (и количество искры) намного хуже,
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, поэтому я просто жестко запрограммировал это).
Изменить 1
Ниже приведены некоторые данные о производительности с помощью +RTS -H512m -N -sstderr -RTS
: