sdk icon indicating copy to clipboard operation
sdk copied to clipboard

Identical on ints is worse than equals on ints

Open jensjoha opened this issue 1 year ago • 2 comments

Using == on two ints I get code like this:

754839  v11 <- LoadField(v10 . kind {final}) [-9223372036854775808, 9223372036854775807] int64
   0x00000000005838a3 <+19>:    mov    0x17(%rax),%rcx

754840  v5 <- EqualityCompare(v11 T{_Smi} == v13 T{_Smi}) T{bool}
   0x00000000005838a7 <+23>:    cmp    $0x61,%rcx
   0x00000000005838ab <+27>:    je     0x5838b6 <StringTokenImpl.isIdentifier+38>
   0x00000000005838ad <+29>:    mov    0x80(%r14),%rax
   0x00000000005838b4 <+36>:    jmp    0x5838ba <StringTokenImpl.isIdentifier+42>
   0x00000000005838b6 <+38>:    mov    0x78(%r14),%rax

754841  ParallelMove rax <- rax
754842  DartReturn:14(v5)
   0x00000000005838ba <+42>:    mov    %rbp,%rsp
   0x00000000005838bd <+45>:    pop    %rbp
   0x00000000005838be <+46>:    ret

(from StringTokenImpl.isIdentifier with @pragma("vm:never-inline") on it).

While I don't understand the 0x80 vs 0x78 and mov %rbp,%rsp and pop %rbp part, it loads the field, compares it to 0x61 (97 aka $a aka IDENTIFIER_TOKEN in the dart code) and returns.

Using identical instead I get this:

754852  v11 <- LoadField(v10 . kind {final}) [-9223372036854775808, 9223372036854775807] int64
   0x00000000005838db <+19>:    mov    0x17(%rax),%rcx

754853  v12 <- BoxInt64(v11 T{int}) [-9223372036854775808, 9223372036854775807] T{int}
   0x00000000005838df <+23>:    mov    %rcx,%rax
   0x00000000005838e2 <+26>:    add    %rax,%rax
   0x00000000005838e5 <+29>:    jno    0x5838f4 <StringTokenImpl.isIdentifier+44>
   0x00000000005838eb <+35>:    call   0x6de61c <stub _iso_stub_AllocateMintSharedWithoutFPURegsStub>
   0x00000000005838f0 <+40>:    mov    %rcx,0x7(%rax)

754854  ParallelMove rax <- rax
754855  v5 <- StrictCompare:12(===, v12 T{int}, v4) T{bool}
   0x00000000005838f4 <+44>:    cmp    $0xc2,%rax
   0x00000000005838fa <+50>:    je     0x583905 <StringTokenImpl.isIdentifier+61>
   0x00000000005838fc <+52>:    mov    0x80(%r14),%rcx
   0x0000000000583903 <+59>:    jmp    0x583909 <StringTokenImpl.isIdentifier+65>
   0x0000000000583905 <+61>:    mov    0x78(%r14),%rcx

754856  ParallelMove rax <- rcx
   0x0000000000583909 <+65>:    mov    %rcx,%rax

754857  DartReturn:14(v5)
   0x000000000058390c <+68>:    mov    %rbp,%rsp
   0x000000000058390f <+71>:    pop    %rbp
   0x0000000000583910 <+72>:    ret

where it has added boxing into the mix, doubling the int to box it, checking (I think) if it is now so big it should do other stuff, then comparing to 0xc2 (aka 194 aka boxed 97).

Changing the scanner/parser from using identical to using == (23f0c0b27b3e797f9f7918735ad3461c34847b11) improved the runtime of the CFE compiling itself by ~0.5-0.6% --- but maybe the VM could just skip the boxing?

/cc @mraleph

jensjoha avatar Oct 01 '24 11:10 jensjoha

Summary: The user reports that using identical on two integers is slower than using == because identical involves boxing the integers, which adds overhead. The user suggests that the VM could skip the boxing step for identical on integers to improve performance.

dart-github-bot avatar Oct 01 '24 11:10 dart-github-bot

While I don't understand the 0x80 vs 0x78 and mov %rbp,%rsp and pop %rbp part

I find the code a bit easier to understand if I have the compiler dump the disassembly instead of various tools.

dart compile exe  \
    --extra-gen-snapshot-options --disassemble-optimized \
    --extra-gen-snapshot-options  --code-comments \
   -v foo.dart --output=z.exe 1>z.exe.log 2>&1

This includes inlining information and some of the magic values, so instead of

   0x00000000005838b6 <+38>:    mov    0x78(%r14),%rax

you get something like

        ;; Inlined [_Timer@[email protected]]
0x7ffa5892b93a    498b5678               movq rdx,[thr+0x78]   true

which tells you the value is true.

rakudrama avatar Oct 19 '24 00:10 rakudrama