Date: Tue, 30 Jan 2001 13:11:09 +0100 Subject: Nachschlag zum Cache Timing Ich habe seit dem Vortrag am letzten Donnerstag mal ein paar Geschwindigkeitsmessungen an meinem Athlon 900 zuhause vorgenommen. Die sind nicht direkt auf Set-Top-Boxen übertragbar, aber es sollte doch zu denken geben. Mein Testprogramm war etwas wie folgendes: static char buf[100]; long a,b,c; int i; str_copy(buf,"blubber foo bar baz"); rdtscl(a); i=str_len(buf); rdtscl(b); i=str_len(buf); rdtscl(c); rdtsc ist auf x86 ab dem Pentium definiert und liest den CPU Cycle Counter aus. Hier ist die Deklaration, falls ihr das auch benutzen möchtet: #define rdtscl(low) \ __asm__ __volatile__ ("rdtsc" : "=a" (low) : : "edx") Diese Instruktuion eröffnet völlig neue Benchmark-Möglichkeiten. Man kann z.B. Cache-Effekte messen. Im Unterschied zu herkömmlichen Benchmarks, wo man eine Routine halt oft genug ausführt, daß die Gesamtlaufzeit in Regionen kommt, wo man mit "time" hinreichend messen kann, führt man die Routine mit rdtsc nur einmal aus. Worum es in dieser Mail geht sind Cache-Effekte. In obigem Programm habe ich die Stringlängen-zählroutine von der libowfat genommen, und gemessen. Am Ende schaue ich mir die Differenzen der Cycle Counter an. Das str_copy ist in obigem Programm enthalten, weil buf sonst nicht im Cache ist. Mit obigem Programm messe ich also die Performanceeinbuße, die ich in Kauf nehme, wenn ich durch exzessiven Bloat eine Routine aus dem Cache geschmissen habe und sie nachgeladen werden muß. Auf dem Athlon ist eine L1 Cache Line 64 Bytes. Die libowfat str_len Routine ist auch 64 Bytes lang, d.h. paßt genau in eine Cache-Line (wat'n Zufall ;-}). Hier sind die Timings: Über zehn Aufrufe: 95 zu 80, d.h. _15%_ Performanceeinbuße, nur weil die Routine nicht im Cache ist! Wem das noch nicht krass genug ist: die 15% sind noch relativ moderat. Das ist so wenig, weil die Daten schon im Level 2 Cache waren (jawoll, es gibt mehr als einen Cache, und die sind unterschiedlich schnell). Wenn wir das str_copy rausnehmen, können wir die Auswirkungen eines Level 2 Cache Misses messen. Warum? Weil Daten und Code auf anderen Pages liegen! Und hier sind die Unterschiede ausgesprochen krass: 300 zu 120 Zyklen, d.h. _250%_ langsamer!! Also, liebe Mitentwickler, ihr sehr schon, daß es ausgesprochen wichtig ist, auch auf Details zu achten, und wenn man diese Verlangsamungen sieht, versteht man vielleicht auch besser, wieso ich so laut gegen Indirektionen wettere -- jede Indirektion schmeißt eine andere Routine aus dem Cache. In diesem Sinne, Felix