{"id":3529,"date":"2018-06-05T00:48:34","date_gmt":"2018-06-04T23:48:34","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=3529"},"modified":"2022-02-16T11:26:10","modified_gmt":"2022-02-16T10:26:10","slug":"c-guns-fold-over-stdtuple-und-erzeugten-assembler-code","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=3529","title":{"rendered":"C++ Guns: fold over std::tuple und erzeugten Assembler Code"},"content":{"rendered":"<p><a href=\"http:\/\/roboblog.fatal-fury.de\/?p=3474\">Part 1: print std::array with std::integer_sequence<\/a><br \/>\n<a href=\"http:\/\/roboblog.fatal-fury.de\/?p=3508\">Part 2: convert tuple to parameter pack<\/a><br \/>\n<a href=\"http:\/\/roboblog.fatal-fury.de\/?p=3514\">Part 3: print std::array with std::apply and fold<\/a><br \/>\n<strong>Part 4: fold over std::tuple und erzeugten Assembler Code<\/strong><br \/>\n<a href=\"http:\/\/roboblog.fatal-fury.de\/?p=3538\">Part 5: fold over std::tuple of std::vector of Types ...<\/a><br \/>\n<a href=\"http:\/\/roboblog.fatal-fury.de\/?p=3617\">Part 6: apply generic lambda to tuple<\/a><br \/>\n<a href=\"http:\/\/roboblog.fatal-fury.de\/?p=4994\">Part 7: Play with std::tuple and std::apply<\/a><\/p>\n<p>Hier ein Ausschnitt aus dem Kniffel Spiel Code. Habe jede g\u00fcltige Kombination als einen Typ dargestellt mit einem gemeinsamen Typ Score, welcher die erzielten Punkte enth\u00e4lt. Um die gesamte Punktzahl zu erhalten, muss \u00fcber jeden Typ im tuple iteriert werden und die einzelnen Punkte aufaddiert. Dies wird mit std::apply und fold erledigt.<br \/>\nAlternativ dazu wird in func2() nur \u00fcber sieben Score Objekte iteriert und auf addiert. Mit Compiler Optimierung O1 ist der generierte Assembler Code mit dem std::apply und fold definitiv besser. Es werden sechs Addition Instruktionen erzeugt. Genau soviel wie ben\u00f6tigt werden um sieben Zahlen zu generieren ;)<\/p>\n<p>Der Assembler Code von func2() hingegen zeigt eine Schleife. Dies finde ich bei so kleinen Datenmengen unn\u00f6tig. Nat\u00fcrlich kann man mit Optimierung O3 loop unrolling aktivieren, aber der erzeugte Code wird damit noch schlechter. Die manuelle Aktivierung mit O1 und -funroll-loops oder -fpeel-loops erzeugt am Ende auch nur sechs Addition Instruktionen, aber dann ist loop unrolling f\u00fcr alle fix size Schleifen aktiviert. Auch f\u00fcr die, wo man es lieber nicht haben m\u00f6chte. <\/p>\n<p>Und nat\u00fcrlich geht mit der func2() Variante die Typ Information verloren. Also, std::apply und fold um \u00fcber Typen zu iterieren. Find ich gut.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nstruct Score \r\n{\r\n    int points = 0;\r\n    \r\n};\r\n\r\nstruct Dreierpasch : Score {\r\n};\r\n\r\nstruct Viererpasch : Score {\r\n};\r\n\r\nstruct FullHouse : Score {\r\n};\r\n\r\nstruct KleineStrasse : Score {\r\n};\r\n\r\nstruct GrosseStrasse : Score {\r\n};\r\n\r\nstruct Kniffel : Score {\r\n};\r\n\r\nstruct Chance : Score {\r\n};\r\n\r\nstruct LowerScore;\r\nnamespace std {\r\n    template&lt;&gt;\r\n    struct tuple_size&lt;LowerScore&gt; : std::integral_constant&lt;size_t,7&gt; {};\r\n}\r\n\r\nstruct LowerScore : std::tuple&lt;Dreierpasch, Viererpasch, FullHouse, KleineStrasse, GrosseStrasse, Kniffel, Chance&gt;\r\n{\r\n    int totalPoints() const {\r\n        auto f = &#x5B;](const auto...x){ return (x.points + ...); };\r\n        return std::apply(f, *this );\r\n    }\r\n};\r\n\r\nauto func(const LowerScore&amp; score) {\r\n    return score.totalPoints();\r\n}\r\n\r\nauto func2(const std::array&lt;Score,7&gt;&amp; score) {\r\n    int points = 0;\r\n    for(const Score&amp; s : score) {\r\n        points += s.points;\r\n    }\r\n    return points;\r\n}\r\n<\/pre>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nfunc(LowerScore const&amp;):\r\n  movl (%rdi), %eax\r\n  addl 4(%rdi), %eax\r\n  addl 8(%rdi), %eax\r\n  addl 12(%rdi), %eax\r\n  addl 16(%rdi), %eax\r\n  addl 20(%rdi), %eax\r\n  addl 24(%rdi), %eax\r\n  ret\r\nfunc2(std::array&lt;Score, 7ul&gt; const&amp;):\r\n  leaq 28(%rdi), %rdx\r\n  movl $0, %eax\r\n.L3:\r\n  addl (%rdi), %eax\r\n  addq $4, %rdi\r\n  cmpq %rdx, %rdi\r\n  jne .L3\r\n  ret\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Part 1: print std::array with std::integer_sequence Part 2: convert tuple to parameter pack Part 3: print std::array with std::apply and fold Part 4: fold over std::tuple und erzeugten Assembler Code Part 5: fold over std::tuple of std::vector of Types ... Part 6: apply generic lambda to tuple Part 7: Play with std::tuple and std::apply Hier [&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-3529","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\/3529","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=3529"}],"version-history":[{"count":3,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3529\/revisions"}],"predecessor-version":[{"id":5000,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3529\/revisions\/5000"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3529"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3529"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3529"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}