MetallicPriest
MetallicPriest

Reputation: 30765

Minimum time a thread can pause in Linux

In my application, threads need to pause for a very little time (100s of clock cycles). One way to pause is to call nanosleep, but I suppose it requires a system call to the kernel. Now I want to pause without going to the kernel.

Note that I have enough cores to run my threads on and I bind each thread to a separate core, so even an instruction that can halt the core for a little while would be good. I am using x86. I just want the thread to halt while pausing. I don't want a busy loop or a system call to the kernel. Is it possible to do this? What is the minimum time I can pause a thread?

Upvotes: 8

Views: 7476

Answers (6)

Steve-o
Steve-o

Reputation: 12866

_mm_pause in a busy-wait loop is the way to go.

Unfortunately the delay it provides can change with each processor family:

http://siyobik.info/main/reference/instruction/PAUSE

Example usage for GCC on Linux:

#include <xmmintrin.h>

int main (void) {
    _mm_pause();
    return 0;
}

Compile with MMX enabled:

gcc -o moo moo.c  -march=native

Also you can always just use inline assembler:

__asm volatile ("pause" ::: "memory");

From some Intel engineers, you might find this useful to determine the cost of pausing:

NOP instruction can be between 0.4-0.5 clocks and PAUSE instruction can consume 38-40 clocks.

http://software.intel.com/en-us/forums/showthread.php?t=48371

Upvotes: 7

Foo Bah
Foo Bah

Reputation: 26271

Why don't you just spin-wait yourself? You can, in a loop, repeatedly call the rdtsc instruction to get the clock cycle count and then just stop if the difference exceeds 100 clock cycles.

I presume it's for a trading system, for which this is a common technique

Upvotes: 1

gby
gby

Reputation: 15218

Generally speaking, for such a short delay, I would think a system call is not practical, because the overhead of system call + scheduling + context switch and back again is going to be way longer then your pause, as you seem to already be aware.

What you are left with is to spin (busy wait) to produce the delay. You can loop reading TSC values to know how much to spin, for example (or applicable cycle counter register for other processors)

Yes, spinning like this indeed wastes power, and if you are running on a CPU with multiple hardware threads, as multi core usually implies, you are also taking execution slots from the other threads needlessly, but unless you have a very very very low overhead system call and scheduler mechanism AND a high res timer, I'd say it's not possible.

Upvotes: 0

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215277

Your only hope of getting timing that precise is using timer_create and having the timer expiration delivered by a signal, I think. With realtime scheduling.

I'm not sure what it could possibly be useful for, though, since you cannot perform any IO in such a small time window, and therefore it should not matter if your code runs 1000 times with a 100ns gap between each run, or 1000 times all together with a 100ms gap at the end.

Upvotes: -2

Peter Lawrey
Peter Lawrey

Reputation: 533530

It depends on what you mean by pause. If by pause you want to stop the thread for a short period of time, only the OS can do this.

However, if by pause you want a very short delay, you can do this with a busy loop. The problem with using such a loop is you don't know how long it is really running for. You can estimate it, but an interrupt can make it longer.

Upvotes: 0

Ed Heal
Ed Heal

Reputation: 60007

no - it is not possible. Either call sleep or select - kernel; or have a loop have wastes time.

Upvotes: -1

Related Questions