Hallo, wie lässt sich die Dauer einer Instruktion ermitteln? Im speziellen Fall geht es auf einem STM32F4 um den Vergleich der UDIV-Instruktion im Vergleich zu einer LSRS, die um 10 bits shiftet (Division durch 1024). Habe leider kein Scope zur Hand.
du könnstest dir beide Implementierungen in assembler ansehen und die cycles zählen http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439b/CHDDIGAC.html sagt dir welcher befehl wie lange braucht. Oder du Startest einen Hardwaretimer vor der Operation und stoppst danach die Differenz ist der wert der dich interessiert. Aber generell meistens verbraten Programme die meiste Zeit an ecken wo man sie nicht vermutet. Bist du sicher des dieser Punkt die "low Hanging Fruit" ist das es sich lohnt hier zu optimieren ?
Danke, das hab ich gesucht! In Assembler hat der Compiler jeweils einen Einzeiler draus gemacht. UDIV xyz oder eben LSRS xyz. Laut der Tabelle braucht der Letztere aber nur einen Cycle im Vergleich zum UDIV, das 2 bis 12 braucht. Es ist auch nicht so, dass ich Zeitprobleme hätte, aber wenns schneller geht, warum nicht :)
pc schrieb: > Habe leider kein Scope zur Hand. Dafür reicht ein Logikanalysator im Gegenwert eines besseren Kantinenessens.
STM32F4 hat 'nen Zyklenzähler in DWT->CYCCNT. UDIV hat eine von den Werten abhängige Zyklenzahl. Aber der Fallback auf LSRS lohnt sich IMHO nur wenn der Wert fest auf einer Zweierpotenz steht (#define oder const). Denn die Überprüfung würde länger dauern... Übrigens ist der C Optimizer durchaus in der Lage diese Fälle zu erkennen um dann die kürzere Instruktion zu verwenden.
pc schrieb: > Es ist auch nicht so, dass ich Zeitprobleme hätte, aber wenns schneller > geht, warum nicht :) Wartbarkeit? Code wird öfters gelesen als geschrieben, von daher sollte man, wenn es keine äußeren Einflüsse gibt, erstmal auf leichtes Verständnis Optimieren, anstatt sich auf angenommene Optimierungen zu stürzen.
Imonbln schrieb: > Wartbarkeit? Code wird öfters gelesen als geschrieben, von daher sollte > man, wenn es keine äußeren Einflüsse gibt, erstmal auf leichtes > Verständnis Optimieren, anstatt sich auf angenommene Optimierungen zu > stürzen. Ob da mit erklärendem Kommentar
1 | val = GetAdcVal()*1487/1000; // compiler macht UDIV daraus |
steht oder
1 | val = GetAdcVal()*1523/1024; // compiler macht 10 shifts daraus |
macht dann auch keinen Unterschied mehr.
pc schrieb: > Ob da mit erklärendem Kommentar > val = GetAdcVal()*1487/1000; // compiler macht UDIV daraus > steht oder > val = GetAdcVal()*1523/1024; // compiler macht 10 shifts daraus > macht dann auch keinen Unterschied mehr. Stimmt in beiden fällen, wäre es wartungsfreundlicher zu erklären was es mit dem Faktor 1.48 auf sich hat. Außerdem glaube ich Kommentaren à la „Compiler macht UDIV daraus“ grundsätzlich nicht, das nächste Update oder eine andere Parametrierung, wird diese Annahme zunichte machen. Von daher würde ich auf solchen Voodoo nicht zu viel Zeit verschwenden oder sehr genau Dokumentieren unter welchen Umständen, die Aussage valide ist. Vielleicht gibt es zu ein paar Nicht Standard Erweiterungen deines Compiler, um die Postuliert Annahme im Kommentar zu erzwingen, aber das ist ein anderes Thema…
Jim M. schrieb: > STM32F4 hat 'nen Zyklenzähler in DWT->CYCCNT. Guter Hinweis, danke. Der ist echt nützlich.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.