9 ms·
Thank you. I ran both through lldb to see why luajit was faster and was confused how luajit was faster despite doing quite a bit more work: luajit loop:
by fpgaminer 8y ago
Thank you. I ran both through lldb to see why luajit was faster and was confused how luajit was faster despite doing quite a bit more work:
luajit loop:
0x12a0effe0: movl %eax, %ebp
0x12a0effe2: movl %ebp, %edi
0x12a0effe4: callq *%rbx
0x12a0effe6: movsd 0x8(%rsp), %xmm0 ; xmm0 = mem[0],zero
0x12a0effec: xorps %xmm7, %xmm7
0x12a0effef: cvtsi2sdl %eax, %xmm7
0x12a0efff3: ucomisd %xmm7, %xmm0
0x12a0efff7: ja 0x12a0effe0
c_hello loop:
0x100000ea0 <+80>: movl %ebx, %edi
0x100000ea2 <+82>: callq 0x100000ee6 ; symbol stub for: plusone
0x100000ea7 <+87>: movl %eax, %ebx
0x100000ea9 <+89>: cmpl %r14d, %ebx
0x100000eac <+92>: jl 0x100000ea0 ; <+80>
0x100000ee6 <+0>: jmpq *0x134(%rip)
I'm still a bit surprised that that extra jumpq is more expensive than all those extra instructions luajit is executing.
EDIT: For those curious, Lua handles all numbers as floating-point; there are no ints in Lua. That's what all the extra instructions are for. Interestingly it looks like LuaJIT is storing the loop variable x as int (in the eax register) and just converting it to floating-point for comparison against "count" each loop. Interesting bending of the rules there.
- glandium 8y agoSo, running under perf stat tells me the luajit version runs very much more instructions (5M vs. 3M with my patched C version), but they run in the same number of cycles (2.5M), with the luajit version using more instructions per cycle. The unpatched C version uses 3.5M instructions, and 3.5M cycles, which is half the number of instructions per cycle compared to the luajit version.
- viraptor 8y agoHow did you patch it? Just compile with "-fno-plt" or something more?
- glandium 8y agodiff --git a/hello.c b/hello.c index 725d5ec..b7b1745 100644 --- a/hello.c +++ b/hello.c @@ -1,3 +1,5 @@ +#define _GNU_SOURCE +#include <dlfcn.h> #include <stdio.h> #include "newplus/plus.h" @@ -7,8 +9,9 @@ void run(int count) long long end; int x = 0; + int (*_plusone)(int) = dlsym(RTLD_DEFAULT, "plusone"); while (x < count) - x = plusone(x); + x = _plusone(x); printf("%lld\n", current_timestamp() - start); } And you need to add -ldl to the link flags. Edit: but yeah, -fno-plt works too.
- ufo 8y agoLua 5.3 introduced actual 64 bit integers but those probably will never get in LuaJIT because its deeply married to the NaN tagging trick, which limits unboxed values to aprox 48 bits.
- TeMPOraL 8y ago> For those curious, Lua handles all numbers as floating-point; there are no ints in Lua. Same as in JavaScript. I'm surprised by that. On the surface, having just floats and no ints sounds like a pretty dumb idea. What am I missing? Is there a reasonable rationale for such choice?
- justincormack 8y agoThere are ints in Lua 5.3, and ffi ints in luajit. But generally, its simpler, why should people care about representations. Lua also let you compike as int only I think.
- TeMPOraL 8y ago> why should people care about representations Because ints are exact, while floats introduce errors with nearly every operation. Representations are important in programming - different ones have different consequences.
- mort96 8y agoWell, doubles can represent all the numbers a 52 bit int can, so there's not a huge reason to not use doubles for whole numbers. It also means that new programmers don't get confused when they do 1/3 and get 1, and the language can be significantly simpler when there's only one number type. Also, when you try to store numbers bigger than 2^52, doubles degrade relatively gracefully, while ints wrap around. There are definitely downsides too, but it's a trade-off, not an exclusively bad decision.