Bei einem Benchmarking einer großen wissenschaftlichen Anwendung habe ich festgestellt, dass sie bei gleichen Eingaben manchmal 10 % langsamer läuft. Nach langem Suchen fand ich heraus, dass die Verlangsamung nur dann auftrat, wenn die Anwendung auf Kern 2 meiner Quad-Core-CPU lief (genauer gesagt auf einem Intel Q6600, der mit 2,4 GHz läuft). Die Anwendung ist eine Single-Thread-Anwendung und verbringt die meiste Zeit mit CPU-intensiven mathematischen Routinen.
Da ich nun weiß, dass ein Kern langsamer ist als die anderen, kann ich genaue Benchmark-Ergebnisse erzielen, indem ich die Prozessoraffinität für alle Durchläufe auf denselben Kern einstelle. Ich möchte jedoch immer noch wissen, warum ein Kern langsamer ist.
Ich habe mehrere einfache Testfälle ausprobiert, um den langsamen Teil der CPU zu ermitteln, aber die Testfälle liefen mit identischen Zeiten, sogar auf dem langsamen Kern 2. Nur die komplexe Anwendung zeigte die Verlangsamung. Hier sind die Testfälle, die ich ausprobiert habe:
-
Fließkommamultiplikation und -addition:
accumulator = accumulator*1.000001 + 0.0001;
-
Trigonometrische Funktionen:
accumulator = sin(accumulator); accumulator = cos(accumulator);
-
Ganzzahlige Addition:
accumulator = accumulator + 1;
-
Speicherkopie beim Versuch, den L2-Cache zu verfehlen:
int stride = 4*1024*1024 + 37; // L2 cache size + small prime number for(long iter=0; iter<iterations; ++iter) { for(int offset=0; offset<stride; ++offset) { for(i=offset; i<array_size; i += stride) { array1[i] = array2[i]; } } }
Die Frage: Warum sollte ein CPU-Kern langsamer sein als die anderen, und welcher Teil der CPU verursacht diese Verlangsamung?
EDITAR: Weitere Tests zeigten einige Heisenbug Verhalten. Wenn ich die Prozessoraffinität explizit einstelle, wird meine Anwendung auf Kern 2 nicht langsamer. Wenn sie jedoch ohne explizit festgelegte Prozessoraffinität auf Kern 2 ausgeführt wird, läuft die Anwendung etwa 10 % langsamer. Das erklärt, warum meine einfachen Testfälle nicht die gleiche Verlangsamung zeigten, da sie alle explizit die Prozessoraffinität festlegten. Es sieht also so aus, als gäbe es einen Prozess, der gerne auf Kern 2 läuft, der aber aus dem Weg geräumt wird, wenn die Prozessoraffinität festgelegt ist.
Unterm Strich: Wenn Sie einen genauen Benchmark eines Single-Thread-Programms auf einem Multicore-Rechner benötigen, sollten Sie die Prozessoraffinität einstellen.