{"id":110,"date":"2010-06-27T21:17:48","date_gmt":"2010-06-27T20:17:48","guid":{"rendered":"http:\/\/blog.blockos.org\/?p=110"},"modified":"2014-09-21T17:11:18","modified_gmt":"2014-09-21T16:11:18","slug":"gcd-and-destroy","status":"publish","type":"post","link":"https:\/\/blog.blockos.org\/?p=110","title":{"rendered":"GCD and destroy"},"content":{"rendered":"<p>Some weeks ago I decided to fix once and for all this bloody <a href=\"http:\/\/en.wikipedia.org\/wiki\/High_dynamic_range_rendering\">hdrr<\/a>. As it requires the framebuffer average log luminance, I decided to compute it be generating a pixel accurate mipmap. So for a 320&#215;240 framebuffer we will have the following downsampling steps : (4,4) (4,4) (5,5) (4,3).<br \/>\nDon&#8217;t ask me why but instead of working on a way to decompose a number, I decided that I needed to find the greatest common divisor of width and height! 10 seconds later thanks to the almighty web search engine I started reading the Wikipedia entry about <a href=\"http:\/\/en.wikipedia.org\/wiki\/Binary_GCD_algorithm\">Binary GCD<\/a>. And after some interweb jumps I ended on this <a href=\"http:\/\/sputsoft.com\/2009\/10\/computing-the-greatest-common-divisor\/\">article<\/a>. The Stein\u2019s algorithm looked cool.<br \/>\nIf you look at Sputsoft code, you&#8217;ll realize that the <strong>shift_to_uneven<\/strong> function removes trailing zeros. This can be optimized using GCC builtins. The builtins we need is <strong>__builtin_ctz<\/strong> that counts trailing zeros.<br \/>\nWe can then replace <strong>shift_to_uneven<\/strong> by: <\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">u &gt;&gt;= __builtin_ctz(u);<\/pre>\n<p>And the GCD function now looks like this:<\/p>\n<p>uint32_t gcd( uint32_t c, uint32_t d )<br \/>\n{<br \/>\n\tuint32_t u,v,s;<\/p>\n<p>\tu = __builtin_ctz(c);<br \/>\n\tv = __builtin_ctz(d);<\/p>\n<p>\ts = (u < v) ? u : v;\n    \t\n\tu = c >> u;<br \/>\n\tv = d >> v;<\/p>\n<p>\twhile(u != v)<br \/>\n\t{<br \/>\n\t\tif(u > v)<br \/>\n\t\t{<br \/>\n\t\t\tu -= v;<br \/>\n\t\t\tu >>= __builtin_ctz(u);<br \/>\n\t\t}<br \/>\n\t\telse<br \/>\n\t\t{<br \/>\n\t\t\tv -= u;<br \/>\n\t\t\tv >>= __builtin_ctz(v);<br \/>\n\t\t}<br \/>\n\t}<br \/>\n\treturn u << s;\n}[\/sourcecode]\n\nTadam!\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Some weeks ago I decided to fix once and for all this bloody hdrr. As it requires the framebuffer average log luminance, I decided to compute it be generating a pixel accurate mipmap. So for a 320&#215;240 framebuffer we will have the following downsampling steps : (4,4) (4,4) (5,5) (4,3).\u2026 <a class=\"continue-reading-link\" href=\"https:\/\/blog.blockos.org\/?p=110\">Continue reading<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[27],"_links":{"self":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts\/110"}],"collection":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=110"}],"version-history":[{"count":28,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts\/110\/revisions"}],"predecessor-version":[{"id":980,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts\/110\/revisions\/980"}],"wp:attachment":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}