{"id":1224,"date":"2012-03-28T09:02:28","date_gmt":"2012-03-28T08:02:28","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=1224"},"modified":"2012-04-09T16:57:49","modified_gmt":"2012-04-09T15:57:49","slug":"faster-code-%e2%80%93-part-4-%e2%80%93-align-memory-again","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=1224","title":{"rendered":"Faster Code \u2013 Part 4 \u2013 align memory again"},"content":{"rendered":"<p>Wie ich im letzten Post erw\u00e4hnt habe, ist es gut wenn Variablen im RAM ausgerichtet vorliegen. Nun muss man aber<br \/>\nnoch bedenken, dass nicht einzelne Variablen aus dem RAM geladen werden, sondern ganze Cache-Zeilen. Nun w\u00e4re es doch auch cool, wenn Arrays auf eine Seitenbreite ausgerichtet sind.<br \/>\nMan stelle sich nur mal vor, zwei Threads die auf zwei CPU Kerne laufen, schreiben in Variablen die in der selben Seite\/Cache-Zeile liegt. Nun muss doch die Seite\/Zeile gegenseitig ausgetauscht werden. Das macht die Sache langsamer. <\/p>\n<p>Um die Seitengr\u00f6\u00dfe in Byte festzustellen, gibt es die Funktion int getpagesize (void). Sie betr\u00e4gt nochmal 4096Byte.<br \/>\nUm eine Adresse die auf eine Seitenbreite ausgerichtet ist zu bekommen, kann man einfach valloc nutzen [1].<\/p>\n<pre><code>\r\n  int *a = (int*)valloc(sizeof(int) *1);\r\n  multipleOf(a);\r\n<\/code>\r\n21e0000 multiple of 2  4  8  16  32  4096 \r\n<\/pre>\n<p>Nat\u00fcrlich ist die Adresse auch auf 64 128 u.s.w. ausgerichtet, aber ich habe mir nicht die M\u00fche gemacht das rauszuschreiben.<\/p>\n<p>Vielleich denken sich jetzt einige: \"Schade, dass new von C++ sowas nicht kann\". Aber keine Sorge. Es gibt ein Trick, der nennt sich \"placement new\" [2]<br \/>\nMan kann new einfach einen schon allokierten Speicher \u00fcbergeben und es wird wie gewohnt ctors etc. ausgerufen.<\/p>\n<pre><code>\r\n  class narf {\r\n    public:\r\n      narf() {cout << \"narf()\\n\";}\r\n      ~narf() {cout << \"~narf()\\n\";}\r\n  };\r\n\r\n  narf* a = (narf*)valloc(sizeof(narf) *1);\r\n  multipleOf(a);\r\n  a = new (a) narf();\r\n  a->~narf();\r\n  free(a);\r\n<\/code>\r\n$ valgrind  .\/a.out \r\n\r\n223c000 multiple of 2  4  8  16  32  4096 \r\nnarf()\r\n~narf()\r\n\r\n==5788== HEAP SUMMARY:\r\n==5788==     in use at exit: 0 bytes in 0 blocks\r\n==5788==   total heap usage: 1 allocs, 1 frees, 1 bytes allocated\r\n==5788== \r\n==5788== All heap blocks were freed -- no leaks are possible\r\n\r\n<\/pre>\n<p>Nicht vergessen den dtor von Hand aufzurufen!<\/p>\n<p>[1] <a href=\"http:\/\/www.gnu.org\/software\/libc\/manual\/html_node\/Aligned-Memory-Blocks.html#Aligned-Memory-Blocks\">http:\/\/www.gnu.org\/software\/libc\/manual\/html_node\/Aligned-Memory-Blocks.html#Aligned-Memory-Blocks<\/a><br \/>\n[2] <a href=\"http:\/\/www.parashift.com\/c++-faq-lite\/dtors.html#faq-11.10\">http:\/\/www.parashift.com\/c++-faq-lite\/dtors.html#faq-11.10<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wie ich im letzten Post erw\u00e4hnt habe, ist es gut wenn Variablen im RAM ausgerichtet vorliegen. Nun muss man aber noch bedenken, dass nicht einzelne Variablen aus dem RAM geladen werden, sondern ganze Cache-Zeilen. Nun w\u00e4re es doch auch cool, wenn Arrays auf eine Seitenbreite ausgerichtet sind. Man stelle sich nur mal vor, zwei Threads [&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-1224","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\/1224","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=1224"}],"version-history":[{"count":10,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/1224\/revisions"}],"predecessor-version":[{"id":1334,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/1224\/revisions\/1334"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1224"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1224"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1224"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}