ITADN

Moving to use a single lookup table

#116Pull Requestfranz1981 创建于 2025-01-06
F
franz1981commented
This is funny here - on Ryzen, the existing code produce this performance ``` Benchmark (size) (specialCharPercentage) Mode Cnt Score Error Units MyBenchmark.benchReplaceBackslashRawCompressedTable3 65536 0 thrpt 20 26783.951 ± 66.355 ops/s MyBenchmark.benchReplaceBackslashRawCompressedTable3:CPI 65536 0 thrpt 2 0.297 clks/insn MyBenchmark.benchReplaceBackslashRawCompressedTable3:IPC 65536 0 thrpt 2 3.370 insns/clk MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-dcache-load-misses 65536 0 thrpt 2 2118.079 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-dcache-loads 65536 0 thrpt 2 263567.211 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-icache-load-misses 65536 0 thrpt 2 0.594 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-icache-loads 65536 0 thrpt 2 268.828 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:branch-misses 65536 0 thrpt 2 34.027 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:branches 65536 0 thrpt 2 82121.699 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:cycles 65536 0 thrpt 2 204572.765 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:dTLB-load-misses 65536 0 thrpt 2 0.073 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:dTLB-loads 65536 0 thrpt 2 4.141 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:iTLB-load-misses 65536 0 thrpt 2 0.256 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:iTLB-loads 65536 0 thrpt 2 0.192 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:instructions 65536 0 thrpt 2 689362.358 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:stalled-cycles-frontend 65536 0 thrpt 2 766.591 #/op ``` which is decent and near to what can be obtained with the existing table approach when there are no special chars - but still is underperforming compared to the whoopy 33K with newish Intel - which seems able to perform 2 lookups in parallel in the same cycle, for each read char. For comparison - the closed pr at https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/pull/114 with Ryzen, was overperforming the existing approach with Intel - even if not by a great margin i.e. ~28K ops/sec Moving to a single table lookup with Ryzen (4) the performance is the best we could achieve i.e. ``` Benchmark (size) (specialCharPercentage) Mode Cnt Score Error Units MyBenchmark.benchReplaceBackslashRawCompressedTable3 65536 0 thrpt 20 38490.297 ± 225.671 ops/s MyBenchmark.benchReplaceBackslashRawCompressedTable3:CPI 65536 0 thrpt 2 0.186 clks/insn MyBenchmark.benchReplaceBackslashRawCompressedTable3:IPC 65536 0 thrpt 2 5.369 insns/clk MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-dcache-load-misses 65536 0 thrpt 2 2098.366 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-dcache-loads 65536 0 thrpt 2 197925.670 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-icache-load-misses 65536 0 thrpt 2 0.656 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:L1-icache-loads 65536 0 thrpt 2 216.512 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:branch-misses 65536 0 thrpt 2 30.163 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:branches 65536 0 thrpt 2 82099.583 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:cycles 65536 0 thrpt 2 140648.734 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:dTLB-load-misses 65536 0 thrpt 2 0.171 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:dTLB-loads 65536 0 thrpt 2 3.432 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:iTLB-load-misses 65536 0 thrpt 2 0.204 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:iTLB-loads 65536 0 thrpt 2 0.195 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:instructions 65536 0 thrpt 2 755059.926 #/op MyBenchmark.benchReplaceBackslashRawCompressedTable3:stalled-cycles-frontend 65536 0 thrpt 2 589.245 #/op ``` IPC now is much better and `L1-dcache-loads ` are way less - as expected. I'll give it a shot on Intel to see how it performs - but I start to think we're moving in a land where the CPU frontend design matter enough to give very different outcome with small changes in code Just for reference., the assembly produced by this version is not really great - which surprise me that it gives so much better performance... ```assembly 0x00007f7b005d75b0: vmovq %xmm0,%rsi 0x00007f7b005d75b5: vmovd %xmm1,%r8d 0x00007f7b005d75ba: movslq %ecx,%rax 0x00007f7b005d75bd: movzbl 0x10(%rsi,%rax,1),%r9d 0x00007f7b005d75c3: mov 0x10(%rdi,%r9,4),%r9d 0x00007f7b005d75c8: cmp %ebx,%r10d 0x00007f7b005d75cb: jae 0x00007f7b005d76cd 0x00007f7b005d75d1: vmovd %r8d,%xmm1 0x00007f7b005d75d6: vmovq %rsi,%xmm0 0x00007f7b005d75db: mov %r9d,%r8d 0x00007f7b005d75de: sar $0x10,%r8d 0x00007f7b005d75e2: lea (%r8,%r10,1),%r13d 0x00007f7b005d75e6: movslq %r10d,%rsi 0x00007f7b005d75e9: mov %r9w,0x10(%rdx,%rsi,1) 0x00007f7b005d75ef: vmovq %xmm0,%r10 0x00007f7b005d75f4: movzbl 0x11(%r10,%rax,1),%r10d 0x00007f7b005d75fa: mov 0x10(%rdi,%r10,4),%r9d 0x00007f7b005d75ff: cmp %ebx,%r13d 0x00007f7b005d7602: jae 0x00007f7b005d76d5 0x00007f7b005d7608: mov %r9d,%r10d 0x00007f7b005d760b: sar $0x10,%r10d 0x00007f7b005d760f: add %r13d,%r10d 0x00007f7b005d7612: movslq %r8d,%r8 0x00007f7b005d7615: add %rsi,%r8 0x00007f7b005d7618: mov %r9w,0x10(%rdx,%r8,1) 0x00007f7b005d761e: vmovq %xmm0,%r8 0x00007f7b005d7623: movzbl 0x12(%r8,%rax,1),%r9d 0x00007f7b005d7629: mov 0x10(%rdi,%r9,4),%r9d 0x00007f7b005d762e: cmp %ebx,%r10d 0x00007f7b005d7631: jae 0x00007f7b005d76c7 0x00007f7b005d7637: mov %r9d,%r8d 0x00007f7b005d763a: sar $0x10,%r8d 0x00007f7b005d763e: lea (%r8,%r10,1),%r13d 0x00007f7b005d7642: movslq %r10d,%rsi 0x00007f7b005d7645: mov %r9w,0x10(%rdx,%rsi,1) 0x00007f7b005d764b: vmovq %xmm0,%r10 0x00007f7b005d7650: movzbl 0x13(%r10,%rax,1),%r10d 0x00007f7b005d7656: mov 0x10(%rdi,%r10,4),%r9d 0x00007f7b005d765b: cmp %ebx,%r13d 0x00007f7b005d765e: jae 0x00007f7b005d76d2 0x00007f7b005d7660: mov %r9d,%r10d 0x00007f7b005d7663: sar $0x10,%r10d 0x00007f7b005d7667: add %r13d,%r10d ; {no_reloc} 0x00007f7b005d766a: movslq %r8d,%r8 0x00007f7b005d766d: add %rsi,%r8 0x00007f7b005d7670: mov %r9w,0x10(%rdx,%r8,1) 0x00007f7b005d7676: add $0x4,%ecx 0x00007f7b005d7679: cmp %r11d,%ecx 0x00007f7b005d767c: jl 0x00007f7b005d75b0 ``` Still an unrolling of 4, but more xmm* spilling, likely due to register pressure
合并状态:未合并 6 条评论