PreFetchCacheLine



  • Hallo zusammen,

    ich bin gestern über die PreFetchCacheLine(MSDN) Funktion gestolpert und finde diese sehr interessant.
    Ich habe mir nun ein bisschen Code zusammen geschrieben um die Cache Line richtig zu befeuern. Ich setze einfach mal vorraus, dass die CPU extrem dämlich ist und ich mich selbst darum kümmern muss. Mir ist natürlich klar, dass das in der Realität anders aussieht.

    Ich habe eine Cache Line Size von 64Byte und folgenden Code

    #define sizearr  10 * 1024 * 1024
    struct DATAFast // Ist 8 Byte groß. Es können 8 in den L1 Cache gleichzeitig geladen werden
    {
    	int a;
    	int b;
    };
    DATAFast pMyDatafast[sizearr];  
    
    static int Faster1()
    {
    	unsigned int index = 5;
    	for (register unsigned int i = 0; i < sizearr; ++i)
    	{
    		pMyDatafast[i].a = pMyDatafast[i].b;
    		if (index-- == 0)
    		{
    			PreFetchCacheLine(1, (void*)&pMyDatafast[i + 3]);
    			index = 7;
    		}
    	}
    	return pMyDatafast[0].a;
    }
    
    void main()
    {
    	int c = 0;
    	for (int i = 0; i < 1000; ++i)
    	{
    		QueryPerformanceCounter(&startFaster1[i]);
    		int a = Faster1();
    		QueryPerformanceCounter(&endeFaster1[i]);
    		c++;
    	}
    
    	__int64 difffaster3 = 0;
    	for (int i = 0; i < 1000; ++i)
    	{
    		difffaster1 += endeFaster1[i].QuadPart - startFaster1[i].QuadPart;
    	}
    	difffaster1 = difffaster1 / 1000;
    }
    

    [url]
    http://www.directupload.net/file/d/3734/eedgc2b5_jpg.htm
    [/url]

    Die Faster1() soll immer dann prefetchen, wenn das (vor-)(vor-)letzte Element in einem 8er Block erreicht wurde. Zeichnung entspricht gerade nicht ganz dem ode aber ich denke worauf ich hinaus will.

    Wie wäre es technisch korrekt, die Daten rechtzeitig zu laden? Ich weiß nämlich nicht, ob meine Variante soweit richtig ist und ob ihr bessere Vorschläge habt.



  • Testerrrr schrieb:

    Ich setze einfach mal v******, dass die CPU extrem dämlich ist und ich mich selbst darum kümmern muss. Mir ist natürlich klar, dass das in der Realität anders aussieht.
    (...)
    Wie wäre es technisch korrekt, die Daten rechtzeitig zu laden? Ich weiß nämlich nicht, ob meine Variante soweit richtig ist und ob ihr bessere Vorschläge habt.

    Wenn du nicht willst dass wir "korrekt" an der Realität messen (die du ja ignorierst) ... woran dann?



  • #define sizearr  10 * 1024 * 1024 //Oh, keine Klammern, kein const int
    struct DATAFast // Ist 8 Byte groß. Es können 8 in den L1 Cache gleichzeitig geladen werden
    //Ah, C
    //Ach, der L1 ist doch Wurst
    {
    	int a;
    	int b;
    };
    
    	for (register unsigned int i = 0; i < sizearr; ++i)//register? 
    //musst du alte Bücher haben!
    //wo ist das loop unrolling, sagern wir mal mit 8?
    
    void main()//nu lass aber mal gut sein mit der Geschichtsstunde. 
    {
    	int c = 0;
    	for (int i = 0; i < 1000; ++i)
    	{
    		QueryPerformanceCounter(&startFaster1[i]);
    		int a = Faster1();
    		QueryPerformanceCounter(&endeFaster1[i]);
    		c++;
    	}
    //schockschwerenot, so misst man also 1000 mal und nimmt das letzte ergebnis
    
    //zum ausgleich multipliziert man es mit 1000 und teilt es mit 1000. 
    //ich weiß einen trick, wie man diese schleife beschleunigen könnte. 
    __int64 difffaster3 = 0;//wirre 3
    for (int i = 0; i < 1000; ++i)
    	{
    		difffaster1 += endeFaster1[i].QuadPart - startFaster1[i].QuadPart;
    	}
    	difffaster1 = difffaster1 / 1000;
    }
    

    Vielleicht schauste mal kurz http://techpubs.sgi.com/library/dynaweb_docs/0650/SGI_Developer/books/OrOn2_PfTune/sgi_html/ch06.html#LE27277-PARENT an.


Anmelden zum Antworten