Registriert: Di Mai 18, 2004 16:45 Beiträge: 2621 Wohnort: Berlin
Programmiersprache: Go, C/C++
Ich hab für meine HashList mit SIMD und Cacheline optimierung hantiert aber bisher mit mäßigen Erfolg. Ist bei 5000 Elementen langsamer als normaler C++ Code aber skaliert mit steigender Elemente Zahl extrem gut. Bei 50000 Elementen hab ich unter 10% mehr Cycles verbraucht, wo die C++ Code Variante dann sogar länger brauchte.
Ich hab also Cacheline Utilization, Branching und Instruction based Sampling gemacht und hab raus bekommen, dass die Grundlast einfach zu hoch ist. Wenn ich den SIMD Code verwende, dann explodiert im Debug Mode die Stackverwaltung. Also beim Start der Funktion tut VC++ den Stack mit 0xDDDDDDDD auffüllen und dann die Variablen im Scope darauf mappen. Das kostet durch die Größe der SIMD Variablen gut doppelt soviel Zeit und die holt der Code nicht mehr raus, also ist 2-4x langsamer. Im Release gibt es dies natürlich nicht und da ist dann SIMD auch schneller als der C++ Code aber dennoch nicht zufriedendstellend. Meine Instruktionsanzahl ist extrem gesunken ~30% aber ich verbrauche viel Zeit mit cache, speicherzugriff und das Pipelining wird nicht gut ausgenutzt, weil ich keine operationen hab, die ich einstreuen kann.
Ich bin leider auch nicht ganz SSE fest, was es der benutzung der richtigen Intrinsics betrifft. Vieleicht hat wer noch eine Idee ? Ich bin aktuell Ratlos, wie ich das ganze noch effizienter hin bekomme, ohne die funktion komplett durch asm aus zu tauschen.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Ich hab den SIMD code wie üblich, in meinem Framework, hinter ein funktions dispatcher gepackt. Der erlaubt mir zur Laufzeit auf die beste optimierung um zu schalten und kostet ein normalen funktionsaufruf, also kann nicht inlined werden, sowie der Stack baut sich auf und ab. Genau das sind die kosten, die noch oben drauf gekommen sind aber die Vorteile waren einfach mehr Wert. Durch den Dispatcher ist der Code wesentlich einfacher zu warten und strikt von systemabhängigen Code getrennt.
Ich hatte noch nach höheren Instruktionen geguckt, die es mit weniger Aufwand abfrühstücken aber nix gefunden. Cachemässig hätte ich nur noch prefetch ausprobieren können aber schon in einem google treffer gelesen, dass das nix bringt, weil dazwischen keine weiteren Instruktionen liegen.
Ich hab ledeglich erfahren, dass ich meine lockfree Queue noch recht einfach optimieren kann aber das hatte hier mit nix zu tun. Hier noch die nützliche Info. Member Variablen sollte man prinzipiell zwischen lesen und schreiben aufteilen und zwischen diesen soviel Platz verbrauchen, dass die in unterschiedliche Cachelines kommen. Was nun passiert ist, dass verschiedene Kerne sich nicht um die Cacheline prügeln, denn die müssen sonnst immer wieder aushandeln wer nun von beiden die Cacheline mit schreibzugriff bekommt und die anderen müssen die immer wieder synchronisieren, damit die nicht auf alte Daten arbeiten. Bei C++ gibt es den modifier violate, welcher sagt, dass der cache garnicht benutzt werden soll und man direkt auf dem Speicherwert arbeitet, die bessere Alternative ist genau diese Technik. Alle Threads die nur lesen wollen, bekommen eine andere Cacheline und werden nicht in den Kampf für die schreib Cacheline gezogen und sind somit viel schneller. Das Beispiel war eine Lockfree Queue, die zur Kommunikation zwischen Threads benutzt wird, die hatte ne Payload von 16Byte und wurde mit 112Byte ungenutzten Datenmüll aufgefüllt, damit sie 128Byte und damit 2 Cachelines groß ist und ist damit wesentlich schneller. Ist die Kommunikation nur einseitig, also alle Threads hämmern rein und ein einzelner Konsumiert hilft quasi kaum, da nur 1 Thread schneller wird.
_________________ "Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren" Benjamin Franklin
Mitglieder in diesem Forum: 0 Mitglieder und 8 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.