2017-01-17 5 views
0

Ich möchte die folgende Struktur in golang von diesem linkSeltsame Code zur Verhinderung falscher Sharing

// Local per-P Pool appendix. 
    57 type poolLocal struct { 
    58  private interface{} // Can be used only by the respective P. 
    59  shared []interface{} // Can be used by any P. 
    60  Mutex     // Protects shared. 
    61  pad  [128]byte  // Prevents false sharing. 
    62 } 

Die obige Struktur nur ein Thread zugegriffen werden kann, zu einer Zeit, diskutieren, wie Mutex verwendet wird. Der Coder sperrt die Struktur am Anfang eines Threads und entsperrt sie, wenn der Thread fertig ist. Der Speicher wird also nicht zwischen Threads geteilt. So nicht mehr als ein Kern wird Zugriff auf den Speicher haben. Also, nach meinem Verständnis, falsche Freigabe kann nicht passieren hier. Wenn falsches Teilen nicht passieren kann, warum puffert der Codierer die Struktur mit zusätzlichen Bytes (Pad [128] Byte)? Ist mein Verständnis falsch?

+5

Ja, Ihr Verständnis ist expliziter sein falsch: "False Sharing" hat nichts damit zu tun, dass mehrere Threads auf denselben Speicher zugreifen (Race Condition wenn man schreibt), aber mit Prozessor Cache Zeilen: Einfach googlen nach "false sharing": – Volker

+0

@Volker Thabk you. Ich habe verstanden. Lass mich geklärt werden. Es seien zwei Threads t1 und t2, die auf den Kernen C1 und C2 laufen. Lassen Sie t1 zuerst laufen (jetzt wartet t2, da es eine stummgeschaltete Sperre gibt). Lassen Sie t1 Daten in den L1-Cache von c1 schreiben (die Cache-Zeile, die unsere Struktur speichert). Jetzt ist t2 in C2 bereit. Der L2-Cache in C2 muss jedoch (nach MESI-Protokoll) auf die neuen Werte aktualisiert werden. Danach kann t2 mit seiner Aufgabe fortfahren. Hier findet die falsche Freigabe statt. Hab ich recht? – user3219492

+0

Beim Auffüllen wird jedem Thread eine Cache-Zeile in L1 zugewiesen, die auf unterschiedliche Speicherpositionen in L2 oder höher verweist. Da jeder Thread an verschiedenen Speicherorten arbeitet, werden sie nicht gemeinsam genutzt und daher auch kein MESI und keine falsche Freigabe. Hab ich recht? – user3219492

Antwort

2

Speicherorte auf der gleichen Cache-Line unterliegen false-sharing, was sehr schlecht für die Leistung ist. Die Größe der Cache-Zeilen reicht je nach Prozessormodell von 32 bis 128 Bytes. 128-Byte-Pad Chance für gleiche Cache-Zeile reduzieren, indem verschiedene Prozesse verwendet wird, und dass improvesthe Performace

wie ich es sehe, würde die folgende wäre besser, als es

type poolLocal struct { 
     _  [64]byte  // Prevents false sharing. 
     private interface{} // Can be used only by the respective P. 
     shared []interface{} // Can be used by any P. 
     Mutex     // Protects shared. 
     _  [64]byte  // Prevents false sharing. 
} 
+0

Hoppla. Ich verstehe nicht, wie das die Antwort auf meine Frage ist. Meine Frage ist, wenn nur ein Thread Zugriff auf einen Speicher hat, kann falsches Teilen nicht passieren und dann hat der Programmierer zusätzliche Bits hinzugefügt. Ich habe es jetzt selbst geklärt (schau dir meine Kommentare an). Ziel ist es, die Größe der Struktur ein Vielfaches der Cache-Zeile zu machen. Warum ist es wichtig, ob es am Anfang und/oder am Ende gepolstert ist? – user3219492

+0

außerdem nach diesem Link: http://www.geeksforgeeks.org/structure-member-alignment-padding-and-data-packing/ der Compiler scheint die Reihenfolge der deklarierten Variablen zu ändern. So hat Ihr Padding-Stil und der, der in Frage gestellt hat, keinen Unterschied – user3219492

+0

@ user3219492 'false-sharing' hat nichts mit Threads zu tun, die auf dasselbe Memory zugreifen. Sie können es sich als ein Leistungsproblem aufgrund von zwei Prozessen vorstellen, die dieselbe "Cache-Zeile" teilen –

Verwandte Themen