Skip to content

YIELD is not how you delay on Arm #3

Description

@WonderfulVoid

On Arm (AArch64), you are using the YIELD instruction to delay when spinning. This is not the purpose of the YIELD instruction. The purpose of the YIELD instruction is to notify the hardware that the current hardware thread should yield to any other hardware thread(s) on the same processor core. Without hardware multithreading (SMT), YIELD is a NOP (it is allocated from the HINT space and unsupported hint opcodes behave as NOPs). NOP's are used for padding and are discarded as quickly as possibly and don't contribute to any delay other than clogging up fetch and decode stages.

Unfortunately, Arm does not have a direct (drop-in) replacement for the x86 PAUSE instruction. Other instruction sequences are possible though. If you prefer an unspecified delay in the 30-40 cycle range, ISB can be used. Using the counter-timer (CNTVCT_EL0), more specific delay periods can be achieved but accuracy is dependent on the machine-specific update rate of the counter-timer. Check this function: https://github.com/ARM-software/progress64/blob/master/src/arch/aarch64.h#L112-L131

In my experience, backoff makes spin locks (e.g. basic spin lock and ticket lock) perform (throughput, fairness) much better. Every time you experience memory contention, backing off should improve the situation. But how long you should back off for best result probably depends on many factors (number of contending threads/cores, interconnect latency, CPU microarchitecture etc). No single answer is going to be optimal for all cases.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions