2012-08-08 4 views
8

Angenommen, im geschwindigkeitskritischen Code haben wir ein Paar Arrays, die häufig zusammen verwendet werden, wobei die genaue Größe keine Rolle spielt, sie muss nur auf etwas Vernünftiges gesetzt werden, z.Potenzen von 2 für die Cache-Freundlichkeit vermeiden

int a[256], b[256]; 

Ist dies möglicherweise eine Pessimierung weil die niedrigen Adressbits gleich sind kann es für die Cache erschwert gleichzeitig beide Arrays zu behandeln? Wäre es besser, z.B. 300 statt 256?

+4

Sie haben zu Recht den Verdacht, dass Zweierpotenzen problematisch sein könnten. Aber es gilt normalerweise nur, wenn Sie mehr als 2 Schritte haben. (vor allem, wenn Sie die L1-Cache-Assoziativität überschreiten) [Hier ein Beispiel, wo es tatsächlich problematisch wird.] (http://stackoverflow.com/questions/8547778/why-is-one-loop-so-much-slower-than -wo-loops) In diesem Beispiel gibt es 4 Arrays - die alle vom Start einer 4k-Seite auf den gleichen Offset ausgerichtet sind. – Mysticial

Antwort

6

Umzug meines Kommentars zu einer Antwort:

Sie sind richtig zu vermuten, dass Kräfte von zwei Kindern problematisch sein könnte. Aber es gilt normalerweise nur, wenn Sie mehr als 2 Schritte haben. Es wird nicht wirklich schlimm, bis Sie Ihre L1 cache associativity überschreiten. Aber schon vorher könnten Sie auf falsche Alias-Probleme stoßen.

Hier zwei Beispiele, wo Kräfte von zwei Kindern tatsächlich problematisch werden:

Im ersten Beispiel gibt es 4-Arrays - alle sind ausgerichtet zum gleichen Offset vom Anfang einer 4k Seite.

Im zweiten Beispiel zerstört das spaltenweise Springen einer Matrix vollständig die Leistung, wenn die Größe eine Zweierpotenz ist.

In jedem Fall, beachten Sie, dass das Schlüsselkonzept ist eigentlich die Ausrichtung der Arrays, nicht die Größe von ihnen. Wenn Sie feststellen, dass Sie in Verlangsamungen geraten, fügen Sie einfach Zwischenräume zwischen Ihren Arrays hinzu, um die Ausrichtung zu unterbrechen.

+0

Ein weiterer nützlicher Trick: Wenn Sie immer nur einzeln auf Einträge zugreifen (und niemals über memcpy o.ä. auf ein "Segment" zugreifen), können Sie versuchen, eine triviale Hash-Funktion auf die Indizes der Arrays anzuwenden. Normalerweise XOR. I.e. greifen Sie immer auf [i^0x67] und b [j^0x34] zu. // Ich habe gerade einen Ort gefunden, an dem das hilft. –

Verwandte Themen