{"id":1195,"date":"2012-03-27T10:18:42","date_gmt":"2012-03-27T09:18:42","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=1195"},"modified":"2012-04-09T16:58:02","modified_gmt":"2012-04-09T15:58:02","slug":"faster-code-part-2","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=1195","title":{"rendered":"Faster Code - Part 2"},"content":{"rendered":"<p>Es geht um std::vector<\/p>\n<blockquote><p>Das i-te Element von vector<> a kann statt mit a[i] e?zienter mit<br \/>\nT::iterator ai = a.begin();<br \/>\nT element = *(ai + i);<br \/>\ndereferenziert werden. Dies entspricht der internen Arbeitsweise des Indexoperators, jedoch<br \/>\nerzeugt dieser bei jedem Elementzugri? einen Iterator auf den Anfang des Containers. Gerade<br \/>\nin Schleifen, in denen gro\u00dfe Datenstr\u00f6me Element f\u00fcr Element durchlaufen werden, emp?ehlt<br \/>\nes sich, einen Iterator einmalig vor der Schleife anzulegen und als Basisadresse zu verwenden.<br \/>\nDadurch verdoppelt sich die Performance im Cache und im Speicher k\u00f6nnen etwa 20 %<br \/>\nGeschwindigkeitszuwachs gemessen werden.\n<\/p><\/blockquote>\n<p>Aus http:\/\/www.rrze.uni-erlangen.de\/dienste\/arbeiten-rechnen\/hpc\/Projekte\/DA_Stengel_cppnuma.pdf Seite 34<\/p>\n<p>Das geht aber wieder gegen die Compiler Optimierung. Leider habe ich mir nicht notiert, wo ich das gelesen habe. Aber wenn man den operator[] benutzt, dann wei\u00df der Compiler, dass man nur durch das Array laufen will. Und nicht irgendwelche Pointerarithmetik.<br \/>\n\/\/ edit<br \/>\nGilt das aber auch f\u00fcr den operator[] einer Klasse und nicht nur f\u00fcr ein RAW Array? Mist, wo hab ich das blos nur gelesen...<\/p>\n<p>Ich habe mal etwas geforscht und folgendes gefunden: in der libstdc++-v3 die mit dem GNU C++ Compiler kommt, wird KEIN Iterator beim Aufruf vom operator[] erzeugt.<br \/>\ngcc-4.7-20120225\/libstdc++-v3\/include\/bits\/stl_vector Zeile 755<\/p>\n<pre><code>\r\n   \/\/ element access\r\n      \/**\r\n       *  @brief  Subscript access to the data contained in the %vector.\r\n       *  @param __n The index of the element for which data should be\r\n       *  accessed.\r\n       *  @return  Read\/write reference to data.\r\n       *\r\n       *  This operator allows for easy, array-style, data access.\r\n       *  Note that data access with this operator is unchecked and\r\n       *  out_of_range lookups are not defined. (For checked lookups\r\n       *  see at().)\r\n       *\/\r\n      reference\r\n      operator[](size_type __n)\r\n      { return *(this->_M_impl._M_start + __n); }\r\n<\/code><\/pre>\n<p>_M_start ist also nur ein Pointer der um __n Element weiter gez\u00e4hlt wird. Kein Iterator zu sehen. Das ist aber Pointer Arithmetik und das \u00e4rgert den Compiler. Kann man das nicht auch so machen?<\/p>\n<pre><code>\r\n { return _M_impl._M_start[__n]); }\r\n<\/code><\/pre>\n<p>Das w\u00e4re dann der [] operator auf ein RAW Array. <\/p>\n<p>Der benutze Compiler im obrigen Pdf ist der 64Bit  Intel C\/C++-Compiler Version  9.1.049. Und damit w\u00e4re der Gnu Compiler schneller. Zumindest in diesem Fall ;) GNU Rockt ;)<\/p>\n<p>Ich habe auch noch ein Codest\u00fcck von SGI gefunden wo ein Iterator benutzt wird.<br \/>\n<a href=\"http:\/\/www.sgi.com\/tech\/stl\/download.html\">http:\/\/www.sgi.com\/tech\/stl\/download.html<\/a> Datei stl_vector.h Zeile 224.<\/p>\n<pre><code>\r\niterator begin() { return _M_start; }\r\nreference operator[](size_type __n) { return *(begin() + __n); }\r\n<\/code><\/pre>\n<p>Der Iterator ist hier nur ein Funktion die ein Pointer zur\u00fcck gibt. Dieser Funktionsaufruf wird bestimmt weg optimiert.<\/p>\n<p>Micht interessiert wie Intel das implementiert hat.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Es geht um std::vector Das i-te Element von vector a kann statt mit a[i] e?zienter mit T::iterator ai = a.begin(); T element = *(ai + i); dereferenziert werden. Dies entspricht der internen Arbeitsweise des Indexoperators, jedoch erzeugt dieser bei jedem Elementzugri? einen Iterator auf den Anfang des Containers. Gerade in Schleifen, in denen gro\u00dfe Datenstr\u00f6me [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[14,17,31,18],"class_list":["post-1195","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-c","tag-cpp","tag-faster-code","tag-linux"],"_links":{"self":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/1195","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=1195"}],"version-history":[{"count":12,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/1195\/revisions"}],"predecessor-version":[{"id":1336,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/1195\/revisions\/1336"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1195"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1195"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1195"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}