สิ่งที่ฉันเข้าใจ Haskell มีเธรดสีเขียว แต่จะมีน้ำหนักเบาขนาดไหน เป็นไปได้ไหมที่จะสร้าง 1 ล้านเธรด?
หรือ 100,000 เธรดจะใช้เวลานานเท่าใด?
สิ่งที่ฉันเข้าใจ Haskell มีเธรดสีเขียว แต่จะมีน้ำหนักเบาขนาดไหน เป็นไปได้ไหมที่จะสร้าง 1 ล้านเธรด?
หรือ 100,000 เธรดจะใช้เวลานานเท่าใด?
จากที่นี่
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.5gh ของฉัน ใช้เวลาน้อยกว่าหนึ่งวินาที
ตั้ง n เป็น 1000000 และการเขียนส่วนที่เหลือของโพสต์นี้เป็นเรื่องยากเนื่องจากระบบปฏิบัติการเพจเพจอย่างบ้าคลั่ง ใช้แรมไปเกินกิ๊กแน่นอน (อย่าให้หมดนะ) หากคุณมี RAM เพียงพอ มันจะทำงานได้เร็วกว่าเวอร์ชัน 100,000 ถึง 10 เท่าอย่างแน่นอน
ตามที่นี่ ขนาดสแต็กเริ่มต้น คือ 1k ดังนั้นฉันคิดว่าตามทฤษฎีแล้วมันเป็นไปได้ที่จะสร้าง 1,000,000 เธรด - สแต็กจะใช้หน่วยความจำประมาณ 1Gb
ใช้การวัดประสิทธิภาพที่นี่ 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 = 1m บน MacBook Pro, i7, RAM 8GB โดยใช้:
$ 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
จากนั้นคอมไพล์โดยไม่มี -threaded:
$ time ./thr
1000000
real 0m2.861s
user 0m2.283s
sys 0m0.572s
และสุดท้าย โดยไม่ต้อง -threaded และมีสแต็กลดลง:
$ time ./thr +RTS -k0.5k
1000000
real 0m2.606s
user 0m2.198s
sys 0m0.404s