2016-05-04 10 views
1

Ich muss Katri Rao Produkt zwischen 2 Matrizen in C implementieren. Mathematisch ist dies eine Spalte wichtiger Zugriff von Daten und ich kann das nicht ändern. Aber wenn ich Preload (PLD-Anweisung in ARMv7) verwende, um jede nächste Schleifendatenvorabzuholen, wird das Problem der Leistung gelöst, anstatt einen Hauptzugriff auf Daten in der Reihe zu verwenden.Prefetch in ARMv7 in C

Wenn ja, wie man richtig vorlädt?

Bitte überprüfen Sie meine Vorbelastung Code unten,

void khatrirao_pref(double *C, double *A, double *B, 
        int nmax, int mmax, int pmax) 
{ 
    int i,k,l; 
    for (i=0;i<nmax;i++) 
    { 
    for (k=0;k<mmax;k++) 
     { 
     asm("PLD [%0]\n\t" :: "r" (A+i+((nmax+1)*k)));  
     for (l=0;l<pmax;l++) 
    { 
      asm("PLD [%0]\n\t" :: "r" (B+i+((nmax+1)*l))); 
      C[i+(nmax*((k*pmax)+l))]=A[i+(nmax*k)]*B[i+(nmax*l)]; 
    }}} 
} 
+0

Wenn Sie immer Spaltenreihenfolge verwenden möchten, überlegen Sie, ob Sie Spalten als Zeilen und Zeilen als Spalten behandeln können, indem Sie den Sinn von Arrayindizes umkehren, wo Sie 'A [Zeile] [Spalte]' verwendet haben 'A [Spalte] [Zeile]'. Dies gibt Ihnen den Caching-Vorteil des Zugriffs auf die Daten in der Speichersequenz. Es ist nicht leicht, etwas zu unternehmen - sorgfältig zu messen und zu testen. –

+0

@ JonathanLeffler Hallo Jonathan, Danke für die Antwort. Aber ich kann es nicht tun. Ich muss mich strikt im Hauptsperrplatz aufhalten. Ich kann die innere Gleichung oder die Reihenfolge der 3 Schleifen oder die Dimensionen von Arrays nicht ändern. Ich kann Prefetch nur verwenden, um die nächsten Schleifendaten von A und B derselben Spalte zu erhalten. Ich weiß, das ist irgendwie merkwürdig, frage ich. Was denken Sie ? – karnajitsen

+0

Wenn Sie mit Ihrem Speicherzugriffsmuster "gegen den Strich" gehen, wird die Leistung definitiv beeinträchtigt. Ein besserer Plan wäre, das gesamte Array vorab in den Cache zu laden, bevor es diesen Code erreicht. Wie Sie geschrieben haben, werden Sie Prefetching nicht helfen; Sie müssen der CPU einen Hinweis geben und ihm dann Zeit geben, das Lesen durchzuführen. – BitBank

Antwort

4

Die Vorspannung Anweisung hat auch seine eigenen Kosten. In der Regel möchten Sie vorlesen, wenn Sie tatsächlich lesen und sich genau profilieren.

aber sagen, dass, wenn diese gcc oder Klappern ist, du bist besser dran mit __builtin_prefetch anstatt explizite Inline asm, weil dadurch ein PLD für Ziele kompiliert, die sie unterstützen (ARMv5TE und später), aber harmlos sein sonst . Ich fand dieses Blog-Post einige Beispiele der realen Welt Nutzung zeigt:

http://www.naftaliharris.com/blog/2x-speedup-with-one-line-of-code/

Dies ist auch eine sehr hilfreiche Link auf das Verständnis der Verwendung von PLD:

http://infocenter.arm.com/help/topic/com.arm.doc.faqs/ka13544.html

Beachten Sie, dass diese Seite zeigt dass es manchmal nachteilig sein kann, PLD zu verwenden. Meine Vermutung ist, dass Sie es nicht zumindest in Ihrer inneren Schleife ausgeben wollen. Sie sollten auf jeden Fall verschiedene Fälle ausprobieren.

Abhängig von den gebräuchlichsten Größen Ihrer Matrizen, können Sie es auch als nützlich empfinden, bestimmte nmax/mmax Werte zu berücksichtigen.

+0

, aber ich benutze ARMv7 Prozessor.Wird __builtin_prefetch dort arbeiten? Ich denke, PLD sollte die Anweisung sein, dies zu tun. – karnajitsen

+0

Ja, so sagen Sie gcc/clang, diese Anweisung zu senden. –

Verwandte Themen