0

I need a sleep that does not issue any system or IO calls for a scenario with Hardware Transactional Memory (these calls would lead to an abort). Sleeping for 1 microsecond as in usleep(1) would be just fine.

This question suggests to implement nested loops to keep the program busy and delay it for some time. However, I want to be able to compile with optimization which would delete these loops.

An idea could be to calculate some sophisticated math equation. Are there approaches to this? The actual time waited does not have to be precise - it should be vaguely the same for multiple runs however.

Community
  • 1
  • 1
mschrimpf
  • 539
  • 2
  • 8
  • 19
  • 1
    Time spent awake (such as to count a loop or perform a lengthy equation) is not sleeping. – mah Mar 18 '14 at 10:45
  • I'm assuming here that you're on Intel's TSX? – Matthew G. Mar 18 '14 at 13:56
  • Also, I'm curious about your use case: Extending transaction lifetimes is generally a bad idea, as it'll needlessly increase the probability of conflict -- unless that's the point? – Matthew G. Mar 18 '14 at 14:05
  • @MatthewG.: yes, it's Intel's TSX (using HLE to be specific). And you are right, the probability increase of a conflict is the point here to compare two algorithms in terms of different transaction runtimes. – mschrimpf Mar 19 '14 at 00:37
  • Well, it'd be interesting to see the results of this. Best wishes! – Matthew G. Mar 19 '14 at 01:11

3 Answers3

1

Try a nop loop with a volatile asm directive:

for (int i = 0; i < 1000; i++) { 
    asm volatile ("nop"); 
} 

The volatile should prevent the optimizer from getting rid of it. If that doesn't do it, then try __volatile__.

Matthew G.
  • 1,298
  • 10
  • 24
0

You can use this code:

#include <time.h>

void delay(int n)
{
    n *= CLOCKS_PER_SEC / 1000;
    clock_t t1 = clock();
    while (clock() <= t1 + n && clock() >= t1);
}

Sometimes (not very often) this function will cause less delay than specified due to clock counter overflow.

Update

Another option is to use a loops like this with volatile counters.

Community
  • 1
  • 1
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
0

The tricky part here is the timing. Querying any sort of timer may well count as an I/O function, depending on the OS.

But if you just want a delay loop, when timing isn't that important, you should look to platform-specific code. For example, there is an Intel-specific intrinsic called _mm_pause that translates to a CPU pause instruction, which basically halts the pipeline until the next memory bus sync comes through. It was designed to be put into a spinlock loop (no point in spinning and requerying an atomic variable until there is a possibility of new information), but it might (might - read the documentation) inhibit the compiler from removing your delay loop as empty.

Sebastian Redl
  • 69,373
  • 8
  • 123
  • 157
  • Alas, this won't work. In the TSX docs, PAUSE is listed as one of the instructions which will unconditionally abort the transaction in any TSX implementation. – Matthew G. Mar 18 '14 at 13:56