Это на самом деле для моего университетского проекта.В моем эссе мне нужно привести доказательства того, что потоки на Haskell создаются быстрее, чем простые потоки ядра.Я знаю, что лучше обратиться к какой-нибудь исследовательской работе, но суть в том, что я должен провести сравнительный анализ самостоятельно.
Вот что я придумал.Я написал две программы на C (с использованием pthreads) и Haskell, которые создают много потоков, но эти потоки абсолютно ничего не делают.Мне нужно измерить только скорость создания потока.
Вот исходный код для программы на C:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
void* thread_main(void*);
int main(int argc, char* argv[])
{
int n,i;
pthread_t *threads;
pthread_attr_t pthread_custom_attr;
if (argc != 2)
{
printf ("Usage: %s n\n where n is no. of threads\n",argv[0]);
return 1;
}
n=atoi(argv[1]);
threads=(pthread_t *)malloc(n*sizeof(*threads));
pthread_attr_init(&pthread_custom_attr);
for (i=0; i<n; i++)
{
pthread_create(&threads[i], &pthread_custom_attr, thread_main, (void *)(0));
}
for (i=0; i<n; i++)
{
pthread_join(threads[i],NULL);
}
}
void* thread_main(void* p)
{
return 0;
}
и для программы на Haskell:
module Main (main) where
import System.IO.Unsafe
import System
import Control.Concurrent
import Control.Exception
children :: MVar [MVar ()]
children = unsafePerformIO (newMVar [])
waitForChildren :: IO ()
waitForChildren = do
cs <- takeMVar children
case cs of
[] -> return ()
m:ms -> do
putMVar children ms
takeMVar m
waitForChildren
forkChild :: IO () -> IO ThreadId
forkChild io = do
mvar <- newEmptyMVar
childs <- takeMVar children
putMVar children (mvar:childs)
forkIO (io `finally` putMVar mvar ())
forkKids :: Int -> IO ()
forkKids 0 = return ()
forkKids n = do
forkChild (threadMain)
forkKids (n-1)
threadMain = return ()
main = do
args <- getArgs
forkKids (read (head args))
waitForChildren
Теперь я запускаю каждую программу с одним и тем же аргументом (например, 10000) и измеряю их время выполнения с помощью time -f%e
, а затем беру среднее арифметическое времени выполнения.Это показывает, что создание потоков на Haskell на порядок быстрее.
Теперь мой вопрос: правильный ли это тест?или есть какой-то фактор, который мне нужно учитывать, чтобы получить точные результаты?
Спасибо