OK, here it is:

First my well known Nim test code:
    
    
    # nim c -d:release k.nim
    import random, math
    
    proc main =
      var s, j: int
      for i in 0 .. 10000000:
        j = rand(7)
        #s += j * j # j ^ 2
        s += j ^ 2
      echo s
    
    main()
    
    
    Run

Compiled with nim c -d:release k.nim with gcc9.1
    
    
            .file       "k.c"
    .L33:
            movl        $7, %edi
            call        rand_v7jZDEs4VOsrcpvk0yo8Rg
            movq        %rax, %rdi
            movl        $2, %esi
            call        roof__e6fgxN584SyDK8XF8s1uig
            addq        %rax, %rbp
            decq        %rbx
            jne .L33
    
    
    Run
    
    
            .file       "stdlib_math.c"
            .text
            .p2align 4
            .globl      roof__e6fgxN584SyDK8XF8s1uig
            .hidden     roof__e6fgxN584SyDK8XF8s1uig
            .type       roof__e6fgxN584SyDK8XF8s1uig, @function
    roof__e6fgxN584SyDK8XF8s1uig:
    .LFB3:
            .cfi_startproc
            movq        %rdi, %rax
            cmpq        $2, %rsi
            je  .L2
            jg  .L3
            testq       %rsi, %rsi
            je  .L9
            cmpq        $1, %rsi
            jne .L5
            ret
            .p2align 4,,10
            .p2align 3
    .L3:
            cmpq        $3, %rsi
            jne .L5
            movq        %rdi, %rdx
            imulq       %rdi, %rdx
            imulq       %rdx, %rax
            ret
            .p2align 4,,10
            .p2align 3
    .L9:
            movl        $1, %eax
            ret
            .p2align 4,,10
            .p2align 3
    .L5:
            movq        %rax, %rdx
            movl        $1, %eax
            jmp .L7
            .p2align 4,,10
            .p2align 3
    .L22:
            imulq       %rdx, %rdx
    .L7:
            testb       $1, %sil
            je  .L8
            imulq       %rdx, %rax
    .L8:
            shrq        %rsi
            jne .L22
            ret
            .p2align 4,,10
            .p2align 3
    .L2:
            imulq       %rdi, %rax
            ret
            .cfi_endproc
    .LFE3:
            .size       roof__e6fgxN584SyDK8XF8s1uig, 
.-roof__e6fgxN584SyDK8XF8s1uig
            .ident      "GCC: (Gentoo 9.1.0 p1.0) 9.1.0"
            .section    .note.GNU-stack,"",@progbits
    
    
    Run

Seems to be not surprising. As roof proc is not inlined, full assembler proc is 
called.

And to verify here timing with your roof proc:
    
    
    $ time ./k
    175032899
    
    real        0m0.172s
    
    
    Run

Plain j * j gives
    
    
    $ time ./k
    175032899
    
    real        0m0.164s
    
    
    
    Run

It is not a big difference of course, but note the rand() and loop overhead. 
For Python we would be happy with the roof proc, but this is Nim. And as I 
wrote above, my static suggestion gives same as j * j. Of course we can use 
-flto, and maybe we should make that the default, then all is inlined and your 
roof proc works perfectly.

Reply via email to