Hab jetzt nur zum Gegencheck den Ransom ähmm Random als lokal funktion eingebaut
Delphi-Quellcode:
procedure internalExecute;
var
i : integer;
x : Byte;
dummy : int64;
RandSeed : integer;
function myRandom(
const ARange: Integer): Integer;
asm
{ ->EAX Range }
{ <-EAX Result }
PUSH EBX
XOR EBX, EBX
IMUL EDX,[EBX].RandSeed,08088405H
INC EDX
MOV [EBX].RandSeed,EDX
MUL EDX
MOV EAX,EDX
POP EBX
end;
begin
QueryPerformanceCounter(dummy);
RandSeed := dummy;
x := 9;
for i:=1
to 1000000
do begin
x := x
xor (myRandom(23223)
mod 255);
//x := x xor (i mod 255);
end;
//*)
SetEvent(fWaitFinish);
end;
und siehe da nun stimmen die Zeiten zu dem was ich mir vorgestellt habe
Code:
Threading (1 Threads : 3289,73 ms
Threading (2 Threads : 1670,74 ms
Threading (4 Threads : 851,50 ms
Threading (8 Threads : 426,44 ms
Damit ich es nochmal verstehe das genau das das Problem ist.
Kern 1 lädt die 64Byte wo die variable RandSeed ist in die CacheLine des Kern1
Kern 2 ... Kern 4 machen das gleiche
da nun einer der Kerne die Variable Randseed ändert, muss der Kern nun die 64Byte aus der CacheLine wieder zurück in den
RAM speichern - und dabei markiert er bei allen anderen Kernen nun das die 64 Byte die die anderen Kerne in der Cacheline haben ungültig sind und diese müssen die nun erneut laden.
- Das passiert aber nur wenn der Kern auch Daten ändert, ein nur lesen wäre kein Problem gewesen
- Je mehr Kerne da nun das ausgeführt hätten, desto langsamer würde das werden (die Anzahl der Threads ist nebensächlich, da wenn 10 Threads auf einem Kern laufen es ja auch nur eine CacheLine gibt) nur die echten Kerne die auch eine CacheLine haben zählen hier
- Wie sicher ist die 64Byte Grenze, und wie kann man das im echten Leben dann sicherstellen das die Variablen sich nicht überschneiden?