2016-08-31 1 views
7

Wir haben einen einfachen Benchmark für den Arbeitsspeicherdurchsatz. Alles was es tut, ist wiederholt für einen großen Speicherblock zu speichern.Warum ist Skylake so viel besser als Broadwell-E für Singlethread-Speicherdurchsatz?

Mit Blick auf die Ergebnisse (für 64-Bit kompiliert) auf einigen verschiedenen Maschinen, Skylake-Maschinen deutlich besser als Broadwell-E, Betriebssystem (Win10-64), Prozessorgeschwindigkeit und RAM-Geschwindigkeit (DDR4-2133) das Gleiche. Wir sprechen nicht ein paar Prozentpunkte, sondern eher einen Faktor von etwa 2. Skylake ist zweikanalig konfiguriert, und die Ergebnisse für Broadwell-E variieren nicht für Dual/Triple/Quad-Channel.

Irgendwelche Ideen, warum dies passieren könnte? Der Code, der in Release in VS2015 kompiliert folgt, und meldet durchschnittliche Zeit, um jede Memcpy abzuschließen an:

64-Bit: 2,2 ms für Skylake vs 4.5ms für Broadwell-E

32-Bit : 2,2 ms für Skylake vs 3,5 ms für Broadwell-E. Wir können einen größeren Speicherdurchsatz auf einem Vierkanal-Broadwell-E-Build erreichen, indem wir mehrere Threads verwenden, und das ist nett, aber ein so drastischer Unterschied für den Single-Thread-Speicherzugriff ist frustrierend. Irgendwelche Gedanken darüber, warum der Unterschied so ausgeprägt ist?

Wir haben auch verschiedene Benchmark-Software verwendet, und sie validieren, was dieses einfache Beispiel zeigt - single-threaded Speicherdurchsatz ist viel besser auf Skylake.

#include <memory> 
#include <Windows.h> 
#include <iostream> 

//Prevent the memcpy from being optimized out of the for loop 
_declspec(noinline) void MemoryCopy(void *destinationMemoryBlock, void *sourceMemoryBlock, size_t size) 
{ 
    memcpy(destinationMemoryBlock, sourceMemoryBlock, size); 
} 

int main() 
{ 
    const int SIZE_OF_BLOCKS = 25000000; 
    const int NUMBER_ITERATIONS = 100; 
    void* sourceMemoryBlock = malloc(SIZE_OF_BLOCKS); 
    void* destinationMemoryBlock = malloc(SIZE_OF_BLOCKS); 
    LARGE_INTEGER Frequency; 
    QueryPerformanceFrequency(&Frequency); 
    while (true) 
    { 
     LONGLONG total = 0; 
     LONGLONG max = 0; 
     LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds; 
     for (int i = 0; i < NUMBER_ITERATIONS; ++i) 
     { 
      QueryPerformanceCounter(&StartingTime); 
      MemoryCopy(destinationMemoryBlock, sourceMemoryBlock, SIZE_OF_BLOCKS); 
      QueryPerformanceCounter(&EndingTime); 
      ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart; 
      ElapsedMicroseconds.QuadPart *= 1000000; 
      ElapsedMicroseconds.QuadPart /= Frequency.QuadPart; 
      total += ElapsedMicroseconds.QuadPart; 
      max = max(ElapsedMicroseconds.QuadPart, max); 
     } 
     std::cout << "Average is " << total*1.0/NUMBER_ITERATIONS/1000.0 << "ms" << std::endl; 
     std::cout << "Max is " << max/1000.0 << "ms" << std::endl; 
    } 
    getchar(); 
} 
+0

Entspricht die Memcpy-Bibliotheksfunktion von MSVC einer Strategie, die auf CPUID oder anderem basiert? z.B. AVX-Schleife gegen 'rep movsb' Haben Sie sichergestellt, dass beide Puffer für alle Tests mindestens 64B-ausgerichtet sind? Hast du die Leistungsindikatoren überprüft, um zu sehen, ob du irgendwelche TLB-Fehler oder nur L3-Cache-Fehler bekommst? (Skylake kann zwei TLB-Wanderungen parallel machen). Ist Ihr Broadwell-E ein Multi-Socket-System (NUMA)? –

+0

Haben Sie das BIOS Ihres Broadwell-Systems überprüft, um sicherzustellen, dass der Prefetch nicht deaktiviert ist oder so? Konnten Sie sich mit anderen Broadwell- oder Haswell-Desktop-Systemen vergleichen? (Ausschließen, dass auf der spezifischen Broadwell-Maschine, an der Sie testen, etwas seltsam ist). –

+1

2.2ms zu kopieren 23.8MiB ist etwa 10.6GiB/s jeweils lesen und schreiben, für gemischte lesen + schreiben. Intel sagt [Skylake i5-6600] (http://ark.intel.com/products/88188) (und andere SKL-Modelle mit DDR4-2133) haben eine theoretische maximale Speicherbandbreite von 34,1 GB/s (oder 31,8 GiB/s). Selbst wenn jede Ladung und jeder Speicher in L3 fehlt und in den Hauptspeicher gehen muss, ist das nur etwa 2/3 des theoretischen Maximums. Das kann für einen einzelnen Thread jedoch normal sein. –

Antwort

2

Einzel-Threaded Speicherbandbreite auf modernen CPUs wird durch max_concurrency/latency des Transfer vom L1D an den Rest des Systems nicht von DRAM-Controller Engpaß begrenzt. Jeder Kern hat 10 Line-Fill-Puffer (LFBs), die ausstehende Anforderungen an/von L1D verfolgen. (Und 16 "Superqueue" -Einträge, die Linien zu/von L2 verfolgen).

Intels Vielkern-Chips haben eine höhere Latenz auf L3/Speicher als Quad-Core- oder Dual-Core-Desktop-/Laptop-Chips, daher ist die Single-Thread-Speicherbandbreite bei einem großen Xeon tatsächlich viel schlechter, obwohl die maximale Gesamtbandbreite mit vielen Threads ist viel besser. Sie haben viel mehr Hops auf dem Ringbus, der Kerne, Speichercontroller und den Systemagenten (PCIe usw.) verbindet.

SKX (Skylake-Server/AVX512, einschließlich der i9 "High-End-Desktop" -Chips) ist wirklich schlecht für diese: L3/Speicher Latenz ist deutlich höher als für Broadwell-E/Broadwell-EP, so Single-Threaded Die Bandbreite ist sogar schlechter als bei einem Broadwell mit einer ähnlichen Core-Zahl. (SKX verwendet ein Mesh anstelle eines Ringbusses, weil das besser skaliert, see this for details on both. Aber anscheinend sind die konstanten Faktoren schlecht in dem neuen Design; vielleicht haben zukünftige Generationen eine bessere L3 Bandbreite/Latenz für kleine/mittlere Core Counts. Kern L2 ist allerdings zu 1MiB gestoßen, vielleicht L3 ist absichtlich langsam um Strom zu sparen.)


Ein Quad oder Dual-Core-Chip benötigt nur ein paar Fäden (vor allem, wenn die Kerne + Nicht-Kern (L3) getaktet werden hoch), um seine Speicherbandbreite zu sättigen, und ein Skylake mit schnellem DDR4 Dual Channel hat ziemlich viel Bandbreite.

Weitere Informationen hierzu finden Sie im Abschnitt Latenzgebundene Plattformen von this answer über x86-Speicherbandbreite. (Und lesen Sie die anderen Teile für Memcpy/memset mit SIMD-Schleifen vs. rep movs/rep stos und NT speichert gegen regelmäßige RFO speichert und mehr.)

Zusammenhang auch: What Every Programmer Should Know About Memory? (2017 Update auf, was immer noch wahr ist und was in das geändert ausgezeichneter Artikel von 2007).

2

Endlich habe ich VTune (Evaluierung) gestartet. Es gibt eine DRAM-gebundene Punktzahl von .602 (zwischen 0 und 1) auf Broadwell-E und .324 auf Skylake, wobei ein großer Teil der Broadwell-E-Verzögerung von Memory Latency kommt. Angesichts der Tatsache, dass die Memory Sticks die gleiche Geschwindigkeit haben (außer Dual-Channel konfiguriert in Skylake und Quad-Kanal in Broadwell-E), meine beste Vermutung ist, dass etwas über den Speicher-Controller in Skylake ist einfach enorm besser.

Es macht den Kauf in die Broadwell-E-Architektur ein viel schwieriger Anruf, und erfordert, dass Sie wirklich die zusätzlichen Kerne brauchen, um es sogar zu berücksichtigen.

Ich habe auch L3/TLB Miss Counts. Auf Broadwell-E war die Anzahl der TLB-Fehlschläge um etwa 20% höher und die der L3-Fehlschläge um etwa 36% höher.

Ich denke nicht, dass dies wirklich eine Antwort für "warum" ist, also werde ich es nicht als solches markieren, aber ist so nah, wie ich denke, dass ich zu einem vorerst komme. Danke für all die hilfreichen Kommentare auf dem Weg.

Verwandte Themen