1 x265中的bcast64 热点函数
static void bcast64(uint8_t* dst, uint8_t val) {
uint64_t bval = 0x0101010101010101ULL * val;
((uint64_t*)dst)[0] = bval;
((uint64_t*)dst)[1] = bval;
((uint64_t*)dst)[2] = bval;
((uint64_t*)dst)[3] = bval;
((uint64_t*)dst)[4] = bval;
((uint64_t*)dst)[5] = bval;
((uint64_t*)dst)[6] = bval;
((uint64_t*)dst)[7] = bval; }
看起来就是吧一个字节平铺为8个字节。
2 simd汇编实现
global bcast64
bcast64:
prefetcht0 [rdi];
vpbroadcastb zmm3, rsi
vmovdqu64 [rdi], zmm3
ret
3 测试
结果发现跑的更慢了,查原因。x265 C代码编译后。
00000000000000a0 <_ZL7bcast64Phh>:
a0: 40 0f b6 f6 movzbl %sil,%esi
a4: 48 b8 01 01 01 01 01 movabs $0x101010101010101,%rax
ab: 01 01 01
ae: 48 0f af f0 imul %rax,%rsi
b2: 48 89 37 mov %rsi,(%rdi)
b5: 48 89 77 08 mov %rsi,0x8(%rdi)
b9: 48 89 77 10 mov %rsi,0x10(%rdi)
bd: 48 89 77 18 mov %rsi,0x18(%rdi)
c1: 48 89 77 20 mov %rsi,0x20(%rdi)
c5: 48 89 77 28 mov %rsi,0x28(%rdi)
c9: 48 89 77 30 mov %rsi,0x30(%rdi)
cd: 48 89 77 38 mov %rsi,0x38(%rdi)
d1: c3 retq
d2: 0f 1f 40 00 nopl 0x0(%rax)
d6: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)
dd: 00 00 00
看起来simd也比simd跑得快
查下intel文档,这些指令的指令周期
vpbroadcastb 3
vmovdqu64 7
看起来也会比C代码编译的快?
intel的普通指令集都是跑在基频,simd指令集一般比基频慢不少,通常只有1.6 - 1.9GHz。
猜测应该是这个原因,导致avx512 没有比C跑得快。
4 手写汇编测试
mov rax, 0x101010101010101
imul rsi, rax
prefetcht1 [rdi];
mov [rdi], rsi
mov [rdi+8], rsi
mov [rdi+16], rsi
mov [rdi+24], rsi
mov [rdi+32], rsi
mov [rdi+40], rsi
mov [rdi+48], rsi
mov [rdi+56], rsi
ret
速度和C代码相当