void* worker(void*)
{
int clk = clock();
float val = 0;
for(int i = 0; i != 100000000; ++i)
{
val += sin(i);
}
printf("val: %f\n", val);
printf("worker: %d ms\n", clock() - clk);
return 0;
}
int main()
{
pthread_t tid;
pthread_create(&tid, NULL, worker, NULL);
int clk = clock();
float val = 0;
for(int i = 0; i != 100000000; ++i)
{
val += sin(i);
}
printf("val: %f\n", val);
printf("main: %d ms\n", clock() - clk);
pthread_join(tid, 0);
return 0;
}
Основной поток и рабочий поток должны работать одинаково быстро, но в результате:
val: 0.782206
worker: 5017 ms
val: 0.782206
main: 8252 ms
Основной поток намного медленнее, я не знаю почему ….
Задача решена. Это проблема компилятора, GCC (MinGW) ведет себя странно в Windows.
Я скомпилировал код в Visual Studio 2012, разницы в скорости нет.
Main thread and the worker thread are supposed to run equally fast, but the result is:
Я никогда не видел многопоточную систему вне ОС реального времени, которая обеспечивала бы такие гарантии. Что касается потоков Windows и всех других систем потоков (я также использую потоки posix, и какими бы ни были легкие потоки в MacOS X и потоки в потоках C #) в настольных системах, я понимаю, что не существует никаких гарантий производительности с точки зрения или как быстро один поток будет по отношению к другому.
Возможное объяснение (предположение) может состоять в том, что, поскольку вы используете современный четырехъядерный процессор, это может повысить тактовую частоту основного ядра. Когда рабочие нагрузки в основном однопоточные, современные системы i5 / i7 / AMD-FX повышают тактовую частоту одного ядра до предварительно установленного уровня, для которого штатное охлаждение может рассеивать тепло. При более параллельных рабочих нагрузках все ядра имеют меньший удар по тактовой частоте, опять же, предварительно оцененный на основе рассеивания тепла, а при простое все ядра снижаются для минимизации энергопотребления. Возможно, что объем фоновой работы в основном выполняется на одном ядре, а количество времени, которое второй поток тратит на второе ядро, недостаточно для оправдания перехода в режим, в котором повышается скорость всех ядер.
Я бы попробовал еще раз с 4 потоками и 10-кратной рабочей нагрузкой. Если у вас есть инструмент, который контролирует загрузку процессора и тактовые частоты, я бы это проверил. Используя эту информацию, вы можете сделать вывод, прав я или нет.
Другим вариантом может быть профилирование и просмотр того, какая часть работы занимает время. Возможно, вызовы ОС занимают больше времени, чем ваша рабочая нагрузка.
Вы также можете протестировать свое программное обеспечение на другом компьютере с другими характеристиками производительности, такими как постоянная тактовая частота или одноядерное. Это даст больше информации.
Может случиться так, что выполнение рабочего потока чередуется с выполнением main, поэтому часть времени выполнения рабочего потока подсчитывается с временем main. Вы можете попробовать положить sleep(10)
(некоторое время больше времени выполнения рабочего и основного) в самом начале рабочего процесса и запускается снова.