{"id":3747,"date":"2018-10-12T10:36:14","date_gmt":"2018-10-12T09:36:14","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=3747"},"modified":"2018-10-12T10:36:14","modified_gmt":"2018-10-12T09:36:14","slug":"c-guns-ofast-in-action","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=3747","title":{"rendered":"C++ Guns: -Ofast in action"},"content":{"rendered":"<p>Mit -Ofast wird bei folgenden Code die Power Funktion weg optimiert und durch die dritte Wurzel ersetzt. <\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nauto func(double MANNING2, double qNorm, double H ) {\r\n    return MANNING2 * qNorm \/ (pow(H,(7.0\/3.0)));\r\n}\r\n<\/pre>\n<p>Im Assembler Code ist nur noch <em>cbrt<\/em> zu erkennen, kein <em>pow<\/em> mehr.<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nfunc(double, double, double):\r\n        subq    $40, %rsp\r\n        movsd   %xmm0, 8(%rsp)    # MANNING2\r\n        movapd  %xmm2, %xmm0      # H nach xmm0 f\u00fcr cbrt\r\n        movsd   %xmm1, 24(%rsp)   # qNorm\r\n        movsd   %xmm2, 16(%rsp)   # H\r\n        call    cbrt              # cbrt(H) nach xmm0\r\n        movsd   16(%rsp), %xmm2   # xmm2 = H\r\n        movsd   24(%rsp), %xmm1   # xmm1 = qNorm\r\n        mulsd   8(%rsp), %xmm1    # xmm1 = MANNING2*qNorm\r\n        addq    $40, %rsp \r\n        mulsd   %xmm2, %xmm2      # xmm2 = H*H\r\n        mulsd   %xmm0, %xmm2      # xmm2 = H*H*cbrt(H)\r\n        divsd   %xmm2, %xmm1      # xmm1 = MANNING2*qNorm \/(H*H*cbrt(H))\r\n        movapd  %xmm1, %xmm0\r\n        ret\r\n<\/pre>\n<p>Der Assembler Code zur\u00fcck nach C++ \u00fcbersetzt gibt folgenden:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nauto func(double MANNING2, double qNorm, double H ) {\r\n    return MANNING2 * qNorm \/ (H*H*cbrt(H));\r\n}\r\n<\/pre>\n<p>Die <em>pow<\/em> Funktion mit zwar bekannten, aber \"unsch\u00f6nen\" Exponenten wurde ersetzt durch eine Multiplikation und eine Power Funktion mit bekannte und \"sch\u00f6nen\" Exponenten: 1\/3<\/p>\n<p>Aber es k\u00f6nnte besser sein. Es f\u00e4llt auf, dass die Funktionsargumente erst einmal auf den Stack gepusht werden. Offenbar braucht die <em>cbrt<\/em> Funktion die Register xmm0, xmm1, xmm2 selbst. Und so m\u00fcssen die Werte eben gesichert werden. Da sie erst danach gebraucht werden. ...<br \/>\nNat\u00fcrlich kann man <em>MANNING2*qNorm<\/em> berechnen bevor vor Nenner der Formel fertig berechnet ist. Mathematisch kann man das tun, die Klammern kann man setzten.<\/p>\n<p>Aber den Compiler st\u00f6rt das nicht. Es wird immer erst <em>cbrt<\/em> vor <em>MANNING2*qNorm<\/em>. Ich denke <em>cbrt<\/em> braucht einfach mehr Zeit als eine Multiplikation. Und daher wird dieser Befehl als erstes ausgef\u00fchrt. Und zwischenzeitlich k\u00f6nnen davon unabh\u00e4ngige Variablen bearbeitet werden.<\/p>\n<p>Aber eine Sache kann dennoch optimiert werden. Indem H als ersten Parameter \u00fcbergeben wird. Dann liegt es gleich im xmm0 Register f\u00fcr cbrt bereit und muss nicht erst dorthin kopiert werden. An der Anzahl der Instruktionen \u00e4ndert dies nichts. Aber die <em>mov<\/em> Operation wird auch erst nach <em>cbrt<\/em> ausgef\u00fchrt.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mit -Ofast wird bei folgenden Code die Power Funktion weg optimiert und durch die dritte Wurzel ersetzt. auto func(double MANNING2, double qNorm, double H ) { return MANNING2 * qNorm \/ (pow(H,(7.0\/3.0))); } Im Assembler Code ist nur noch cbrt zu erkennen, kein pow mehr. func(double, double, double): subq $40, %rsp movsd %xmm0, 8(%rsp) # [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[17],"class_list":["post-3747","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-cpp"],"_links":{"self":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3747","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3747"}],"version-history":[{"count":7,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3747\/revisions"}],"predecessor-version":[{"id":3754,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3747\/revisions\/3754"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3747"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3747"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3747"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}