zakkak
zakkak

Reputation: 1971

Putting a thread to sleep (c pthreads)

I am using pthreads and am trying to put a thread to sleep for X seconds.

I have tried sleep(), nanosleep(), pthread_cond_timedwait() (waiting on a fake mutexlock for X seconds), pthread_yield(), checking the time every time the thread wakes up, to see if it's its time to run, and finally just busy waiting for X seconds.

The problem is that, although all these methods do work fine considering the result, they do not give the performance results I would expect. Performance is measured in throughput (replies per second) and not in time.

In my configuration I am running 3 software threads over 2 simulated physical cores (VirtualBox running Ubuntu Server). I would expect to get better performance when putting 1 of the 3 threads to sleep, as the other 2 threads have one dedicated physical core to run on. However, I get the exact opposite behavior (with all my approaches): increasing the sleep time gives worse performance. (Note that the sleeping thread's workload is 130-300ms.)

Could it be because of the virtualization (the host machine has 4 cores)? Could it be because the methods I'm using operate in a similar way to my approach using pthread_yield?

How are sleep() and nanosleep() implemented? Do they use signals? Do you think an implementation using a signal handler and alarm() would be a better approach? What happens when I call pthread_cond_wait()? How is it implemented?

I have also tried using chrt to change the scheduling policies, with no luck.

Upvotes: 3

Views: 6722

Answers (2)

Chetan Ahuja
Chetan Ahuja

Reputation: 941

I agree with @Aaron Digulla that you'll never get an answer to a performance question by hit-and-trial and guesswork. But more than that, I'm not sure you are measuring the right thing, at least going by your claims that longer the sleep between your periodic thread, worse your throughput is. Going by that logic, you could set the sleep period to an infinite number (basically larger than your measurement period) and your throughput should be the worst of the set. Is that the case ?

Please note that measuring server throughput can be a tricky business subject to many pitfalls in measurement and client setup. Here are some example of how easy it is to be tricked by your synthetic benchmark numbers: http://www.teamquest.com/pdfs/whitepaper/load-test.pdf

Read that article if you're interested in performance measurements at all. It's pure gold.

Upvotes: 3

Aaron Digulla
Aaron Digulla

Reputation: 328536

  1. Run your code through a profiler to see where the time is spent. Otherwise, you'll just be guessing and in my experience, these guesses are wrong 90% of the time.

  2. alarm() could help but it should actually do what sleep() does, so I wouldn't really expect a difference.

Here are some ideas what could cause this:

  • Cache flushes. If your two work threads use the caches very well, then switching to the new thread could mean a cache flush which can be very expensive. Here, the idea is that the worker threads can fill more cache if the sleeper leaves them alone for longer periods of time.

  • The two worker threads need a resource which the sleeper hogs/locks.

  • How well did you measure performance? Maybe you measured some other effect (desktop search indexing your computer, whatever)

To get to the bottom of this, you'll have to reduce the code function by function until the desired behavior starts to appear + running it in a profiler to check for the unexpected.

Upvotes: 1

Related Questions