Kann x86 ein enges Geschäft mit einer größeren Auslastung, die es vollständig enthält, neu ordnen?

Entwicklerhandbuch für Intel® 64- und IA-32-Architekturen sagt:

8.2.3.4 Ladevorgänge können mit früheren Speichern an verschiedenen Orten neu angeordnet werden
Das Intel-64-Speicher-Bestellmodell ermöglicht die Neuordnung einer Ladung mit einem früheren Speicher an einem anderen Speicherort. Ladungen werden jedoch nicht mit Läden am selben Ort nachbestellt.

Was ist mit Lasten, die sich teilweise oder vollständig mit früheren Speichern überschneiden, aber nicht die gleiche Startadresse haben? (Siehe das Ende dieser Seite für einen bestimmten Fall)

Nehmen Sie den folgenden C-ähnlichen Code an:

// lock - pointer to an aligned int64 variable
// threadNum - integer in the range 0..7
// volatiles here just to show direct r/w of the memory as it was suggested in the comments
int TryLock(volatile INT64* lock, INT64 threadNum)
{
    if (0 != *lock)
        return 0;                           // another thread already had the lock

    ((volatile INT8*)lock)[threadNum] = 1;  // take the lock by setting our byte

    if (1LL << 8*threadNum != *lock)
    {   // another thread set its byte between our 1st and 2nd check.   unset ours
        ((volatile INT8*)lock)[threadNum] = 0;
        return 0;
    }

    return 1;
}

der sein x64 asm-Äquivalent:

; rcx - address of an aligned int64 variable
; rdx - integer in the range 0..7
TryLock PROC
cmp qword ptr [rcx], 0
jne @fail

mov r8, rdx
mov rax, 8
mul rdx

mov byte ptr [rcx+r8], 1

bts rdx, rax
cmp qword ptr [rcx], rdx
jz  @success

mov byte ptr [rcx+r8], 0

@fail:
mov rax, 0
ret

@success:
mov rax, 1
ret

Angenommen, TryLock wird gleichzeitig in zwei Threads ausgeführt:

INT64 lock = 0;

void Thread_1() {  TryLock(&lock, 1);  }
void Thread_5() {  TryLock(&lock, 5);  }
Die Frage

Das((INT8*)lock)[1] = 1; und((INT8*)lock)[5] = 1; Stores befinden sich nicht am selben Speicherort wie die 64-Bit-Last vonlock. Sie sind jedoch jeweils vollständig in dieser Ladung enthalten. "Zählt" das also als derselbe Ort? Es scheint unmöglich, dass eine CPU das kann.

Wie wäre es mit((INT8*)lock)[0] = 1? Die Adresse des Ladens ist dann die gleiche wie die Adresse der folgenden Ladung. Befinden sich diese Operationen "am selben Ort", auch wenn dies im vorherigen Fall nicht der Fall war?

p.s. Bitte beachten Sie, dass es sich bei der Frage nicht um C / Asm-Code handelt, sondern um das Verhalten der x86-CPUs.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage