I am trying to compile some code for arm (v7a), that had a
#if defined(__arm__)
__yield();
#endif
added in this pull-request
The other branches have YieldProcessor()
for MSC and _mm_pause()
or __builtin_ia32_pause()
for x86 and x86-64.
The symbol __yield
is not found by the compiler, a arm-v7a-linux-gnueabihf-gcc
7.3.1 with -mcpu=cortex-a9 -mtune=cortex-a9 -march=armv7-a
options. Is such symbol defined on some other ARM platforms, later Gcc, or Clang?
In the headers that come with the compiler all I could find is __gnu_parallel::__yield
being an inline wrapper over sched_yield()
, which I suppose is equivalent to the std::this_thread::yield()
that the code calls after 100 iterations calling __yield()
. So I think it's not that. But I didn't see __yield
in gcc documentation either.
CodePudding user response:
The __yield
intrinsic is specified as part of the ARM C Language Extensions (see 8.4 "Hints"). It emits the yield
instruction, which is the rough equivalent of x86 pause
. It is intended precisely for situations like waiting on a spinlock; it keeps the CPU from hammering on the cache line excessively (which hurts performance), possibly saves some power, and, in case of a hyperthreading CPU, makes more computational units available to the other logical processor.
(Note that it is purely a CPU function, and not an OS or library call; it doesn't yield a CPU timeslice to the operating system like the similarly named pause()
or sched_yield()
or std::this_thread::yield()
calls would do.)
Although GCC supports some of the ACLE intrinsics, it seems to be missing this one. You should be able to substitute with asm volatile("yield");
. The yield
instruction has no architectural effect (it executes like nop
) so no register or memory clobbers are needed.