Was ist die maximale theoretische Geschwindigkeit-up für eine einfache binäre Subtraktion SSE fällig?

StackOverflow https://stackoverflow.com/questions/1466907

Frage

Bei dem Versuch, um herauszufinden, ob mein Code des innere Schleife ist auf meinem Teil Barriere eine Hardware-Design Barriere oder einen Mangel an Verständnis zu treffen. Es ist ein bisschen mehr, aber die einfachste Frage, die ich mit oben kommen kann, ist wie folgt zu beantworten:

Wenn ich den folgenden Code:

float px[32768],py[32768],pz[32768];
float xref, yref, zref, deltax, deltay, deltaz;

initialize_with_random(px);
initialize_with_random(py);
initialize_with_random(pz);

for(i=0;i<32768-1;i++) {
  xref=px[i];
  yref=py[i];
  zref=pz[i];
  for(j=0;j<32768-1;j++ {
    deltx=xref-px[j];
    delty=yref-py[j];
    deltz=zref-pz[j];
  } }

Welche Art von maximaler theoretischer Geschwindigkeit würde ich, indem Sie auf SSE-Befehle in einer Situation sehen kann, wo ich die vollständige Kontrolle über Code (Montag, intrinsics, was auch immer), aber keine Kontrolle über die Laufzeitumgebung andere als Architektur (dh es ist eine Multi-User-Umgebung, so kann ich nichts tun, wie die OS-Kernel Zeit zu meinem speziellen Prozess zuzuordnet).

Im Moment habe ich mit meinem Code eine Geschwindigkeit von bis 3x bin zu sehen, als ich gedacht hätte mit SSE mir viel mehr Vektor Tiefe geben würde als die 3x beschleunigen anzeigt (vermutlich die 3x beschleunigen sagt mir, ich habe eine 4x maximale theoretische Durchsatz). (Ich habe versucht, Dinge wie lassen deltx / delty / deltz sein Arrays, falls der Compiler nicht klug genug war, um Auto-Förderung sie, aber ich sehe nur noch 3x beschleunigen.) Ich bin mit dem Intel C Compiler mit der entsprechende Compiler-Flags für die Vektorisierung, aber kein intrinsics offensichtlich.

War es hilfreich?

Lösung

Es hängt von der CPU. Aber der theoretische max nicht über 4x erhalten. Ich weiß nicht, von einer CPU, die mehr als ein SSE-Befehl pro Taktzyklus ausführen kann, was bedeutet, dass es höchstens Compute 4 Werte pro Zyklus.

Die meisten CPUs tun kann mindestens ein Floating-Point-skalare Befehl pro Zyklus, so dass in diesem Fall, dass Sie ein theoretisches Maximum von einem 4-fach-Speedup sehen würden.

Aber Sie werden den spezifischen Befehlsdurchsatz für die CPU nachschauen müssen Sie laufen weiter.

Ein praktisches Speedup von 3x ist ziemlich gut aber.

Andere Tipps

Ich glaube, Sie würden wahrscheinlich irgendwie die innere Schleife verschachteln müssen. Der 3-Komponenten-Vektor wird immer sofort erledigt, aber das ist nur 3 Operationen auf einmal. Um auf 4, dann würden Sie 3 Komponenten aus dem ersten Vektor tun, und 1 von den nächsten, dann 2 und 2, und so weiter. Wenn Sie irgendeine Art von Warteschlange, dass Lasten etabliert und verarbeitet die Daten 4 Komponenten zu einem Zeitpunkt, es dann nach trennen, die funktionieren könnte.

Edit: Sie könnten die innere Schleife abrollen zu tun 4 Vektoren pro Iteration (vorausgesetzt, die Array-Größe ist immer ein Vielfaches von 4). Das würde erreichen, was ich oben gesagt.

Bedenken Sie: Wie breit ist ein Schwimmer? Wie breit ist die SSEx Anweisung? Das Verhältnis sollte sollten Ihnen eine Art von vernünftiger Obergrenze.

Es ist auch erwähnenswert, dass Out-of-Order-Rohre havok mit immer guten Schätzungen von Speedup spielen.

Sie sollten prüfen Schleife Tiling - so, wie Sie Werte in der inneren Schleife zugreifen ist wahrscheinlich verursacht eine Menge Dresche in der L1-Datencache. Es ist nicht so schlimm, weil alles, was wahrscheinlich noch in der L2 paßt bei 384 KB, aber es ist leicht eine Größenordnung Unterschied zwischen einem L1-Cache-Treffer und einem L2-Cache-Treffer, so könnte dies einen großen Unterschied für Sie macht.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top