How much overhead is there when creating a thread?

Viewed 62537

I just reviewed some really terrible code - code that sends messages on a serial port by creating a new thread to package and assemble the message in a new thread for every single message sent. Yes, for every message a pthread is created, bits are properly set up, then the thread terminates. I haven't a clue why anyone would do such a thing, but it raises the question - how much overhead is there when actually creating a thread?

12 Answers

It is indeed very system dependent, I tested @Nafnlaus code:

#include <thread>

int main(int argc, char** argv)
{
  for (volatile int i = 0; i < 500000; i++)
    std::thread([](){}).detach();
  return 0;
}

On my Desktop Ryzen 5 2600:

windows 10, compiled with MSVC 2019 release adding std::chrono calls around it to time it. Idle (only Firefox with 217 tabs):

It took around 20 seconds (20.274, 19.910, 20.608) (also ~20 seconds with Firefox closed)

Ubuntu 18.04 compiled with:

g++ main.cpp -std=c++11 -lpthread -O3 -o thread

timed with:

time ./thread

It took around 5 seconds (5.595, 5.230, 5.297)

The same code on my raspberry pi 3B compiled with:

g++ main.cpp -std=c++11 -lpthread -O3 -o thread

timed with:

time ./thread

took around 15 seconds (16.225, 14.689, 16.235)

Interesting.

I tested with my FreeBSD PCs and got the following results:

FreeBSD 12-STABLE, Core i3-8100T, 8GB RAM: 9.523sec<br/>
FreeBSD 12.1-RELEASE, Core i5-6600K, 16GB: 8.045sec

You need to do

sysctl kern.threads.max_threads_per_proc=500100

though.

Core i3-8100T is pretty slow but the results are not very different. Rather the CPU clocks seem to be more relevant: i3-8100T 3.1GHz vs i5-6600k 3.50GHz.

As others have mentioned, this seems to be very OS dependent. On my Core i5-8350U running Win10, it took 118 seconds which indicates an overhead of around 237 uS per thread (I suspect that the virus scanner and all the other rubbish IT installed is really slowing it down too). Dual core Xeon E5-2667 v4 running Windows Server 2016 took 41.4 seconds (82 uS per thread), but it's also running a lot of IT garbage in the background including the virus scanner. I think a better approach is to implement a queue with a thread that continuously processes whatever is in the queue to avoid the overhead of creating and destroying the thread everytime.

Related