views:

153

answers:

5

Hey all,

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?

+1  A: 

There is some overhead in thread creation, but comparing it with usually slow baud rates of the serial port (19200 bits/sec being the most common), it just doesn't matter.

ruslik
+1  A: 

I have always been told that thread creation is cheap, especially when compared to the alternative of creating a process. If the program you are talking about does not have a lot of operations that need to run concurrently then threading might not be necessary, and judging by what you wrote this might well be the case. Some literature to back me up:

http://www.personal.kent.edu/~rmuhamma/OpSystems/Myos/threads.htm

Threads are cheap in the sense that

  1. They only need a stack and storage for registers therefore, threads are cheap to create.

  2. Threads use very little resources of an operating system in which they are working. That is, threads do not need new address space, global data, program code or operating system resources.

  3. Context switching are fast when working with threads. The reason is that we only have to save and/or restore PC, SP and registers.

More of the same here.

In Operating System Concepts 8th Edition (page 155) the authors write about the benefits of threading:

Allocating memory and resources for process creation is costly. Because threads share the resource of the process to which they belong, it is more economical to create and context-switch threads. Empirically gauging the difference in overhead can be difficult, but in general it is much more time consuming to create and manage processes than threads. In Solaris, for example, creating a process is about thirty times slower than is creating a thread, and context switching is about five times slower.

typoknig
But the alternative is probably a single reused thread, or a thread pool, not a process.
Matthew Flaschen
@Matthew Flaschen I meant the alternative to creating any thread, not an alternative to creating a thread(s) in the way the question describes :)
typoknig
Actually process creation is cheaper than thread creation. The fork part of processes creation has basically no cost as the memory pages are duplicated at the hardware level. See what the google chrome team found: http://www.hanselman.com/blog/MicrosoftIE8AndGoogleChromeProcessesAreTheNewThreads.aspx
Martin York
@Martin York according to my text books (and my professors) process creation is more costly than thread creation. I will add an excerpt from one of my text books so you can judge for yourself.
typoknig
@ typoknig: It was true in the old days. I am not saying it is free but it is a myth that it is very expensive. See the article I linked in my last comment.
Martin York
@Martin York the article seems to say that process creation is faster than it once was because of `"this thing called Moore's Law that keeps marching on"`, but that does not compare process to threads on an level playing field. If process creation has gotten faster by an order of magnitude then thread creation would also have gotten faster. In my understanding, there is no way creating a process can ever be done faster than creating a thread because a process will always have more stuff in it than a thread.
typoknig
Yes you quotes are from text books that are OLD. In the old days a fork() required the OS to generate a copy of each memory page that the processes was using. Modern versions of the kernel have moved fork implementation into the protected realm and now use a copy on write technique (that basically means only one page (that page with the current stack frame) needs to be copied at the fork() point). See: http://www.cis.upenn.edu/~jms/cw-fork.pdf
Martin York
@typoknig: The problem with thread creation it involves a lot of work setting up a new stack on the other hand processes creation noways is very cheap as the pages used by the processes are copied only when needed thus your forked process in-effect are sharing the same memory pages. Please read the first article a little more closely.
Martin York
The advantage of threads: Quicker to switch, data is easily shared. The advantage of fork: processes protection (if the process dies it does nto affect the other processes).
Martin York
@Martin York The link you provided is not dated, but its newest reference is 1990. My book is in its 8th edition and was copyrighted in 2009. The original version of my book was published in 1985 which is still newer than most of the references in the link you provided. The link you provided does not compare processes and threads, in fact it does not even mention threads. I would totally agree with your most recent comment, but I still think (based on what I have been taught and what my references say) process creation will always be more expensive than thread creation.
typoknig
@typoknig: Try it and see. It is the only way to know for sure.
Martin York
@Martin York I actually have, and that is the only reason I would even try to stand my ground talking about this with you since you obviously know your stuff with such a big number next to your name :) I am in Advanced Operating Systems right now and most of the semester has been spent on POSIX threads. My professor had an example program which timed the creation of a thread vs. the creation of a process. Process creation always took considerably longer. The program was written in C and run in RedHat, I will see if I can get it from him.
typoknig
Id did not know RedHAt was still around :-) . What version of the Kernel are they using?
Martin York
Are you comparing fork/exec against thread creation? This is definitively more costly than thread creation (because of the exec). But is not equivalent. You just want to compare the fork time against thread creation as you can write the child code in the same application (just like a thread). Here are my two versions: fork vs pthread_create. http://padfly.com/threadVsfork Admittedly I have nothing for the child to do but I create 1000 children in either and it takes 0 time (or its so fast that time XXX records zero).
Martin York
[Alpha:~/X] myork% ./thread 1000Start: 717836Wait: 352700All: 1070536
Martin York
[Alpha:~/X] myork% ./fork 1000Start: 22628Wait: 1439All: 24067
Martin York
The above times were generate using the code posted here http://padfly.com/threadVsfork Running on Darwin Kernel Version 10.4.0. Each version generates 1000 children (which do nothing and then exit). Though I would not rely on the absolute values of a clock() as a timing mechanism I think this shows that the cost of fork() is actually smaller. Now I will concede that different OS will have different characteristics based. Windows for example will not fair as well but Unix like OS running a modern kernel will behave in this manner. Older Kernels that do not use copy on write will also be slower
Martin York
@typoking: This is getting to heavy for a thread discussion. I have started a question: http://stackoverflow.com/questions/3934992/fair-comparison-of-fork-vs-thread
Martin York
+4  A: 

You definitely do not want to do this. Create a single thread or a pool of threads and just signal when messages are available. Upon receiving the signal, the thread can perform any necessary message processing.

In terms of overhead, thread creation/destruction, especially on Windows, is fairly expensive. Somewhere on the order of tens of microseconds, to be specific. It should, for the most part, only be done at the start/end of an app, with the possible exception of dynamically resized thread pools.

Michael Goldshteyn
Yes, an "eternal" dedicated worker thread would also solve the possible MT problems.
ruslik
A: 

Thread creation and computing in a thread is pretty expensive. All data strucutres need to be set up, the thread registered with the kernel and a thread switch must occur so that the new thread actually gets executed (in an unspecified and unpredictable time). Executing thread.start does not mean that the thread main function is called immediately. As the article (mentioned by typoking) points out creation of a thread is cheap only compared to the creation of a process. Overall, it is pretty expensive.

I would never use a thread

  • for a short computation
  • a computation where I need the result in my flow of code (that means, I am starting the thread and wait for it to return the result of it's computation

In your example, it would make sense (as has already been pointed out) to create a thread that handles all of the serial communication and is eternal.

hth

Mario

Mario The Spoon
A: 

...sends Messages on a serial port ... for every message a pthread is created, bits are properly set up, then the thread terminates. ...how much overhead is there when actually creating a thread?

This is highly system specific. For example, last time I used VMS threading was nightmarishly slow (been years, but from memory one thread could create something like 10 more per second (and if you kept that up for a few seconds without threads exiting you'd core)), whereas on Linux you can probably create thousands. If you want to know exactly, benchmark it on your system. But, it's not much use just knowing that without knowing more about the messages: whether they average 5 bytes or 100k, whether they're sent contiguously or the line idles in between, and what the latency requirements for the app are are all as relevant to the appropriateness of the code's thread use as any absolute measurement of thread creation overhead. And performance may not have needed to be the dominant design consideration.

Tony