ITADN

Simplified branchless version

#115Pull Requestfranz1981 创建于 2025-01-05
F
franz1981commented
This replace #114 as anticipated by https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/pull/114#issuecomment-2569562217 The numbers are way better than any version implemented so far, and it doesn't contains branches (apart from for exit conditions). I believe this can be made way slimmer and looks more similar to what I've linked before... That's the tight loop right now ```assembly 0x00007fc7ec1dd7f0: movslq %r8d,%rsi 0x00007fc7ec1dd7f3: vmovq %xmm0,%r10 0x00007fc7ec1dd7f8: movzbl 0x10(%r10,%rsi,1),%r9d 0x00007fc7ec1dd7fe: lea (%r9,%r9,1),%eax 0x00007fc7ec1dd802: movswl 0x10(%rbx,%rax,2),%edi 0x00007fc7ec1dd807: cmp %ecx,%r11d 0x00007fc7ec1dd80a: jae 0x00007fc7ec1dd93c 0x00007fc7ec1dd810: movswl 0x12(%rbx,%rax,2),%r13d 0x00007fc7ec1dd816: lea (%r11,%r13,1),%eax 0x00007fc7ec1dd81a: movslq %r11d,%r14 0x00007fc7ec1dd81d: mov %di,0x10(%rdx,%r14,1) 0x00007fc7ec1dd823: movzbl 0x11(%r10,%rsi,1),%r9d 0x00007fc7ec1dd829: lea (%r9,%r9,1),%r10d 0x00007fc7ec1dd82d: movswl 0x10(%rbx,%r10,2),%edi 0x00007fc7ec1dd833: cmp %ecx,%eax 0x00007fc7ec1dd835: jae 0x00007fc7ec1dd945 0x00007fc7ec1dd83b: movswl 0x12(%rbx,%r10,2),%r11d 0x00007fc7ec1dd841: add %eax,%r11d 0x00007fc7ec1dd844: movslq %r13d,%r10 0x00007fc7ec1dd847: add %r14,%r10 0x00007fc7ec1dd84a: mov %di,0x10(%rdx,%r10,1) 0x00007fc7ec1dd850: vmovq %xmm0,%r10 0x00007fc7ec1dd855: movzbl 0x12(%r10,%rsi,1),%r9d 0x00007fc7ec1dd85b: lea (%r9,%r9,1),%r10d 0x00007fc7ec1dd85f: movswl 0x10(%rbx,%r10,2),%edi 0x00007fc7ec1dd865: cmp %ecx,%r11d 0x00007fc7ec1dd868: jae 0x00007fc7ec1dd938 0x00007fc7ec1dd86e: movswl 0x12(%rbx,%r10,2),%r10d ; {no_reloc} 0x00007fc7ec1dd874: lea (%r11,%r10,1),%eax 0x00007fc7ec1dd878: movslq %r11d,%r13 0x00007fc7ec1dd87b: mov %di,0x10(%rdx,%r13,1) 0x00007fc7ec1dd881: vmovq %xmm0,%r11 0x00007fc7ec1dd886: movzbl 0x13(%r11,%rsi,1),%r9d 0x00007fc7ec1dd88c: lea (%r9,%r9,1),%r11d 0x00007fc7ec1dd890: movswl 0x10(%rbx,%r11,2),%edi 0x00007fc7ec1dd896: cmp %ecx,%eax 0x00007fc7ec1dd898: jae 0x00007fc7ec1dd941 0x00007fc7ec1dd89e: movswl 0x12(%rbx,%r11,2),%r11d 0x00007fc7ec1dd8a4: add %eax,%r11d 0x00007fc7ec1dd8a7: movslq %r10d,%r10 0x00007fc7ec1dd8aa: add %r13,%r10 0x00007fc7ec1dd8ad: mov %di,0x10(%rdx,%r10,1) 0x00007fc7ec1dd8b3: add $0x4,%r8d 0x00007fc7ec1dd8b7: cmp %ebp,%r8d 0x00007fc7ec1dd8ba: jl 0x00007fc7ec1dd7f0 ``` Which shows many `lea` and `cmp` to perform bound checks - which are very unwelcome. Numbers instead, on my Intel, are great: ``` Benchmark (size) (specialCharPercentage) Mode Cnt Score Error Units MyBenchmark.benchReplaceBackslashRawCompressedTable3 65536 3 thrpt 20 33411.750 ± 275.661 ops/s MyBenchmark.benchReplaceBackslashRawCompressedTable3:CPI 65536 3 thrpt 2 0.207 clks/insn MyBenchmark.benchReplaceBackslashRawCompressedTable3:IPC 65536 3 thrpt 2 4.831 insns/clk MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-dcache-load-misses 65536 3 thrpt 2 2140.825 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-dcache-loads 65536 3 thrpt 2 196843.063 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-dcache-stores 65536 3 thrpt 2 65633.492 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-icache-load-misses 65536 3 thrpt 2 16.361 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:LLC-load-misses 65536 3 thrpt 2 0.125 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:LLC-loads 65536 3 thrpt 2 0.937 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:LLC-store-misses 65536 3 thrpt 2 0.045 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:LLC-stores 65536 3 thrpt 2 0.470 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:branch-misses 65536 3 thrpt 2 20.104 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:branches 65536 3 thrpt 2 82029.327 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:cycles 65536 3 thrpt 2 142668.208 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:dTLB-load-misses 65536 3 thrpt 2 0.136 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:dTLB-loads 65536 3 thrpt 2 196800.660 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:dTLB-store-misses 65536 3 thrpt 2 0.156 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:dTLB-stores 65536 3 thrpt 2 65578.583 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:iTLB-load-misses 65536 3 thrpt 2 1.072 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:instructions 65536 3 thrpt 2 689147.120 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3 65536 50 thrpt 20 30872.965 ± 5102.334 ops/s MyBenchmark.benchReplaceBackslashRawCompressedTable3:CPI 65536 50 thrpt 2 0.209 clks/insn MyBenchmark.benchReplaceBackslashRawCompressedTable3:IPC 65536 50 thrpt 2 4.777 insns/clk MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-dcache-load-misses 65536 50 thrpt 2 2632.432 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-dcache-loads 65536 50 thrpt 2 196543.393 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-dcache-stores 65536 50 thrpt 2 65537.601 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-icache-load-misses 65536 50 thrpt 2 18.997 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:LLC-load-misses 65536 50 thrpt 2 0.440 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:LLC-loads 65536 50 thrpt 2 1.370 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:LLC-store-misses 65536 50 thrpt 2 0.017 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:LLC-stores 65536 50 thrpt 2 0.551 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:branch-misses 65536 50 thrpt 2 19.496 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:branches 65536 50 thrpt 2 81899.156 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:cycles 65536 50 thrpt 2 143983.603 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:dTLB-load-misses 65536 50 thrpt 2 0.110 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:dTLB-loads 65536 50 thrpt 2 196853.398 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:dTLB-store-misses 65536 50 thrpt 2 0.162 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:dTLB-stores 65536 50 thrpt 2 65589.683 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:iTLB-load-misses 65536 50 thrpt 2 1.043 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:instructions 65536 50 thrpt 2 687801.973 #/op ``` The uops analysis is [here](https://uica.uops.info/?code=loop%3A%0D%0Amovslq%20%25r8d%2C%25rsi%0D%0Avmovq%20%20%25xmm0%2C%25r10%0D%0Amovzbl%200x10(%25r10%2C%25rsi%2C1)%2C%25r9d%0D%0Alea%20%20%20%20(%25r9%2C%25r9%2C1)%2C%25eax%0D%0Amovswl%200x10(%25rbx%2C%25rax%2C2)%2C%25edi%0D%0Acmp%20%20%20%20%25ecx%2C%25r11d%0D%0Ajae%20%20%20%20bound_check%0D%0Amovswl%200x12(%25rbx%2C%25rax%2C2)%2C%25r13d%0D%0Alea%20%20%20%20(%25r11%2C%25r13%2C1)%2C%25eax%0D%0Amovslq%20%25r11d%2C%25r14%0D%0Amov%20%20%20%20%25di%2C0x10(%25rdx%2C%25r14%2C1)%0D%0Amovzbl%200x11(%25r10%2C%25rsi%2C1)%2C%25r9d%0D%0Alea%20%20%20%20(%25r9%2C%25r9%2C1)%2C%25r10d%0D%0Amovswl%200x10(%25rbx%2C%25r10%2C2)%2C%25edi%0D%0Acmp%20%20%20%20%25ecx%2C%25eax%0D%0Ajae%20%20%20%20bound_check%0D%0Amovswl%200x12(%25rbx%2C%25r10%2C2)%2C%25r11d%0D%0Aadd%20%20%20%20%25eax%2C%25r11d%0D%0Amovslq%20%25r13d%2C%25r10%0D%0Aadd%20%20%20%20%25r14%2C%25r10%0D%0Amov%20%20%20%20%25di%2C0x10(%25rdx%2C%25r10%2C1)%0D%0Avmovq%20%20%25xmm0%2C%25r10%0D%0Amovzbl%200x12(%25r10%2C%25rsi%2C1)%2C%25r9d%0D%0Alea%20%20%20%20(%25r9%2C%25r9%2C1)%2C%25r10d%0D%0Amovswl%200x10(%25rbx%2C%25r10%2C2)%2C%25edi%0D%0Acmp%20%20%20%20%25ecx%2C%25r11d%0D%0Ajae%20%20%20%20bound_check%0D%0Amovswl%200x12(%25rbx%2C%25r10%2C2)%2C%25r10d%0D%0Alea%20%20%20%20(%25r11%2C%25r10%2C1)%2C%25eax%0D%0Amovslq%20%25r11d%2C%25r13%0D%0Amov%20%20%20%20%25di%2C0x10(%25rdx%2C%25r13%2C1)%0D%0Avmovq%20%20%25xmm0%2C%25r11%0D%0Amovzbl%200x13(%25r11%2C%25rsi%2C1)%2C%25r9d%0D%0Alea%20%20%20%20(%25r9%2C%25r9%2C1)%2C%25r11d%0D%0Amovswl%200x10(%25rbx%2C%25r11%2C2)%2C%25edi%0D%0Acmp%20%20%20%20%25ecx%2C%25eax%0D%0Ajae%20%20%20%20bound_check%0D%0Amovswl%200x12(%25rbx%2C%25r11%2C2)%2C%25r11d%0D%0Aadd%20%20%20%20%25eax%2C%25r11d%0D%0Amovslq%20%25r10d%2C%25r10%0D%0Aadd%20%20%20%20%25r13%2C%25r10%0D%0Amov%20%20%20%20%25di%2C0x10(%25rdx%2C%25r10%2C1)%0D%0Aadd%20%20%20%20%240x4%2C%25r8d%0D%0Acmp%20%20%20%20%25ebp%2C%25r8d%0D%0Ajl%20%20%20%20%20loop%0D%0A%0D%0A&syntax=asATT&uArchs=SKL&tools=uiCA&tools=IACA3&tools=IACA23&tools=llvm&tools=OSACA&tools=CQA&alignment=0&uiCAHtmlOptions=traceTable&uiCAHtmlOptions=graph&uiCAHtmlOptions=dependencies)
合并状态:未合并 2 条评论