Сколько времени нужно, чтобы создать 1 миллион потоков в Haskell?

Что я понимаю, у Хаскелла есть зеленые нити. Но насколько они легки. Можно ли создать 1 миллион потоков?

Или сколько времени займет 100 000 потоков?

4 ответа

отсюда

import Control.Concurrent
import Control.Monad

n = 100000

main = do
    left  <- newEmptyMVar
    right <- foldM make left [0..n-1]
    putMVar right 0    -- bang!
    x <- takeMVar left -- wait for completion
    print x
 where
    make l n = do
       r <- newEmptyMVar
       forkIO (thread n l r)
       return r

thread :: Int -> MVar Int -> MVar Int -> IO ()
thread _ l r = do
   v <- takeMVar r
   putMVar l $! v+1

на моем не совсем 2.5-ом ноутбуке это занимает меньше секунды.

установите n на 1000000, и будет трудно написать остальную часть этого поста, потому что ОС пейджинговая как сумасшедшая. определенно используя больше, чем концерт оперативной памяти (не дайте ей закончить). Если у вас достаточно оперативной памяти, она точно будет работать в 10 раз больше, чем версия 100000.

В соответствии с этим, размер стека по умолчанию равен 1 КБ, поэтому я предполагаю, что теоретически было бы возможно создать 1 000 000 потоков - стек занимал бы около 1 ГБ памяти.

Используя тест здесь, http://www.reddit.com/r/programming/comments/a4n7s/stackless_python_outperforms_googles_go/c0ftumi

Вы можете повысить производительность для каждого эталонного теста, уменьшив размер стека потоков до такого, который соответствует эталонному тесту. Например, потоки 1M со стеком 512 байт на поток занимают 2,7 с.

$ time ./A +RTS -s -k0.5k

В этом синтетическом тестовом случае порождение аппаратных потоков приводит к значительным накладным расходам. Работа только с зелеными нитями выглядит как предпочтительный вариант. Обратите внимание, что порождение зеленых нитей в Haskell действительно дешево. Я перезапустил вышеупомянутую программу с n = 1 м на MacBook Pro, i7, 8 ГБ ОЗУ, используя:

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.6.3

Скомпилировано с -threaded и -rtsopts:

$ time ./thr
1000000

 real   0m5.974s
 user   0m3.748s
 sys    0m2.406s

Уменьшение стека помогает немного:

$ time ./thr +RTS -k0.5k
1000000

 real   0m4.804s
 user   0m3.090s
 sys    0m1.923s

Затем компилируется без -поточной:

$ time ./thr
1000000

 real   0m2.861s
 user   0m2.283s
 sys    0m0.572s

И, наконец, без многопоточных и с уменьшенным стеком:

$ time ./thr +RTS -k0.5k
1000000

 real   0m2.606s
 user   0m2.198s
 sys    0m0.404s
Другие вопросы по тегам