Home > Back-end >  Is there a __yield() intrinsic on Arm?
Is there a __yield() intrinsic on Arm?

Time:11-24

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.

  • Related