{"id":3090,"date":"2017-06-15T10:36:11","date_gmt":"2017-06-15T09:36:11","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=3090"},"modified":"2017-06-15T10:37:57","modified_gmt":"2017-06-15T09:37:57","slug":"fortran-parameter-variables-in-module-evaluated-at-compile-or-runtime","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=3090","title":{"rendered":"FORTRAN: parameter variables in module evaluated at compile or runtime?"},"content":{"rendered":"<p>Suggest you habe a fortran module with a collection of mathematical constant like PI.<\/p>\n<pre><code>\r\nmodule constant_m\r\n  real, parameter :: PI = 3.1314_8\r\nend module\r\n<\/code><\/pre>\n<p>Now you <strong>use<\/strong> this module in a function which calculate the circumcenter of a circle with given radius. <\/p>\n<pre><code>\r\nfunction U(r) \r\n  use constant_m\r\n  implicit none\r\n  real, intent(in) :: r\r\n  real :: U\r\n  U = 2*PI*r\r\nend function\r\n<\/code><\/pre>\n<p>Will the expression <strong>2*PI<\/strong> be evaluated a compile or runtime?<br \/>\nLets check the generated assember code!<br \/>\n...<br \/>\nAnd you'll see only crap.<\/p>\n<p>Let's start with an simpler example. Replace every real to integer. Truncate PI to 3, thats fair enough. And remove the \"2*\" expression. Somewhere in the assembler code are there must be the expression y=3*x.<br \/>\nHere it is:<br \/>\ngfortran  --save-temps -O1 -c constants.F90  circle.F90 <\/p>\n<pre><code>\r\n  movl\t4(%esp), %eax        % Store the adress of r from stack pointer into eax\r\n  movl\t(%eax), %eax         % Dereference adress and store value from r into eax\r\n  leal\t(%eax,%eax,2), %eax  % eax = eax + 2*eax \r\n<\/code><\/pre>\n<p>The last line is the one. The compiler optimize the multiplicaton with 3 to an assembler instrctuin which performs a multiplication with 2 and an addition.<br \/>\nWhat we not see is a constant \"3\" in assember code. Or a assembler register filled with \"3\". <\/p>\n<p>Lets add the \"2*\" and see whats happens.<\/p>\n<pre><code>\r\n  movl\t4(%esp), %eax\r\n  movl\t(%eax), %eax\r\n  leal\t(%eax,%eax,2), %eax\r\n  addl\t%eax, %eax\r\n<\/code><\/pre>\n<p>Only the last line is new. The compiler decide that x+x is more performance than 2*x. Cute.<\/p>\n<p>Okay lets have some fun. We force the compiler to evaluate (2*PI) first. (2*PI)*r<br \/>\nAnd the resulting assembler code is the same HAHA.<\/p>\n<p>Okay back to topic. We see that integer, parameter variables in modules are evaluated at compile time. Lets switch back to real.<\/p>\n<p>Now the assembler code looks a litte bit more complicated:<\/p>\n<pre><code>\r\n  flds\t.LC0@GOTOFF(%eax)   % Load constant into floading point register\r\n  movl\t4(%esp), %eax       % Store value from r into eax\r\n  fmuls\t(%eax)              % Multiply the constant with r and put the result back in eax\r\n.LC0:\r\n  .long\t1086918230          % The constand 2*PI\r\n<\/code><\/pre>\n<p>Now you can see a constant in assember as a 4byte iteger. Its only one constant, so I guess its 2*PI here.<br \/>\nThis constant is loaded into a floting point register. The value from r is loaded into a second register. Then both get multiplyed. Thats all. Only a single multiplaction.<\/p>\n<p>PARAMETER VARIABLES IN MODULE ARE EVALUATED AT COMPILE TIME! :D<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Suggest you habe a fortran module with a collection of mathematical constant like PI. module constant_m real, parameter :: PI = 3.1314_8 end module Now you use this module in a function which calculate the circumcenter of a circle with given radius. function U(r) use constant_m implicit none real, intent(in) :: r real :: U [&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":[30],"class_list":["post-3090","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-fortran"],"_links":{"self":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3090","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=3090"}],"version-history":[{"count":5,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3090\/revisions"}],"predecessor-version":[{"id":3095,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3090\/revisions\/3095"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3090"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3090"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3090"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}