3
votes

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.

2
why dont use a mutex or a semaphore? keeping the thread sleeping only the time it needsJarry
Can you please give example code, along with actual performance numbers (e.g., from the time command), that demonstrates your issue?Jay Sullivan
How much work are your threads performing? How long are you sleeping? how often? don't forget about context switching chewing up precious cpu cycles.Dave Rager
@Jarry and how would i hold the mutex or semaphore for X seconds? Could you give an example of what you have in mind?zakkak
Sorry but you've never defined what you mean by "performance" and "results" in your question. There's no real answer to "how do I improve performance" until you define the exact quantity you're measuring to determine performance.chetan

2 Answers

3
votes

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.

1
votes
  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.