Skip to content

Faster gebp_kernel for neon

I found that the gebp_kernel used by eigen neon is 3px4/2px4/1px4 by default. This is reasonable on x86. However, arm neon has 32 registers, and a larger size gebp_kernel can be used to get better data reuse to improve performance.

Therefore, I implement gebp_kernel 3px8/2px8/1px8 on eigen (3px8 24 registers for c, 3 for a, 1 for b). In addition, I set the default L1/L2/L3 on arm64 as 64KB/1MB/2MB. lilianhuang/eigen@9a10e015

The performance comparison with original implementation is as follows:

fp32
mnk orgin optimize(gflops)
256 34.95 38.35
512 39.87 43.14
1024 42.80 44.38
1152 43.26 45.25

fp16
mnk orgin optimize(gflops)
256 65.19 70.72
512 78.82 86.02
1024 83.97 90.15
1152 86.35 91.07

double
mnk orgin optimize(gflops)
256 16.07 18.96
512 16.72 19.91
1024 17.68 20.36
1152 18.16 20.01

platform : Ampere® Altra
Architecture: aarch64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 128
On-line CPU(s) list: 0-127
Vendor ID: ARM
Model name: Neoverse-N1
Model: 1
Thread(s) per core: 1
Core(s) per socket: 64
Socket(s): 2
Stepping: r3p1
CPU max MHz: 3000.0000
CPU min MHz: 1000.0000
BogoMIPS: 50.00
Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp ssbs
Caches (sum of all):
L1d: 8 MiB (128 instances)
L1i: 8 MiB (128 instances)
L2: 128 MiB (128 instances)

bench_gemm.cpp

Edited by Lianhuang Li