同样的AVX指令集代码在Intel Core和AMD Ryzen之间有着巨大的性能差距

如何解决同样的AVX指令集代码在Intel Core和AMD Ryzen之间有着巨大的性能差距

我想使用AVX指令集来加速从8通道图像到8通道图像的卷积操作。我使用 3x3 卷积核。我的代码如下:

        const float* kptr = kernels;
        const float* bptr = biases;

        __m256 _out0 = _mm256_loadu_ps(bptr);
        __m256 _out1 = _mm256_setzero_ps();
        __m256 _out2 = _mm256_setzero_ps();

        for (int i = 0; i < 8; i ++)
        {
            const __m256 _r00 = _mm256_broadcast_ss(tl + i);
            const __m256 _r01 = _mm256_broadcast_ss(tc + i);
            const __m256 _r02 = _mm256_broadcast_ss(tr + i);
            const __m256 _r03 = _mm256_broadcast_ss(ml + i);
            const __m256 _r04 = _mm256_broadcast_ss(mc + i);
            const __m256 _r05 = _mm256_broadcast_ss(mr + i);
            const __m256 _r06 = _mm256_broadcast_ss(bl + i);
            const __m256 _r07 = _mm256_broadcast_ss(bc + i);
            const __m256 _r08 = _mm256_broadcast_ss(br + i);

            const __m256 _k00 = _mm256_loadu_ps(kptr + i * 72);
            const __m256 _k01 = _mm256_loadu_ps(kptr + i * 72 + 8);
            const __m256 _k02 = _mm256_loadu_ps(kptr + i * 72 + 16);
            const __m256 _k03 = _mm256_loadu_ps(kptr + i * 72 + 24);
            const __m256 _k04 = _mm256_loadu_ps(kptr + i * 72 + 32);
            const __m256 _k05 = _mm256_loadu_ps(kptr + i * 72 + 40);
            const __m256 _k06 = _mm256_loadu_ps(kptr + i * 72 + 48);
            const __m256 _k07 = _mm256_loadu_ps(kptr + i * 72 + 56);
            const __m256 _k08 = _mm256_loadu_ps(kptr + i * 72 + 64);

            _out0 = _mm256_fmadd_ps(_r00,_k00,_out0);
            _out1 = _mm256_fmadd_ps(_r01,_k01,_out1);
            _out2 = _mm256_fmadd_ps(_r02,_k02,_out2);
            _out0 = _mm256_fmadd_ps(_r03,_k03,_out0);
            _out1 = _mm256_fmadd_ps(_r04,_k04,_out1);
            _out2 = _mm256_fmadd_ps(_r05,_k05,_out2);
            _out0 = _mm256_fmadd_ps(_r06,_k06,_out0);
            _out1 = _mm256_fmadd_ps(_r07,_k07,_out1);
            _out2 = _mm256_fmadd_ps(_r08,_k08,_out2);
        }
        _out0 = _mm256_max_ps(_mm256_add_ps(_out0,_mm256_add_ps(_out1,_out2)),_mm256_setzero_ps());

        _mm256_storeu_ps(outMat,_out0);

在锐龙上,这非常有效。在 R5 2600 和 R5 3500U 上测试,与经过编译器优化的普通 C++ 代码相比,我可以获得 2-4 倍的性能提升。但在英特尔酷睿 CPU 上,在 i7 8750H 和 i3 4170 上测试,它甚至比带有编译器优化的普通 C++ 代码慢 50%。实际上,在这种情况下,3500U 比 i7 8750H 快 4 倍。

我对此感到困惑。我发现Intel CPU中最耗时的指令是fmadd指令,但是用等效的avx指令替换fmadd后仍然没有任何改进。

我也考虑过寄存器数量的限制,但是在尝试减少__mm256变量的数量后,情况可能会变得更糟。

编译器和参数都一样,我是用msvc2019编译的,我什至用了同样的二进制文件。

权重(kptr)的内存布局是CHWB,输入图像像素(tlbr)是BHWC。

在测试过程中,我注意到在同样的场景下,i7 8750h是满载,而2600是35%左右,性能是前者的8倍。

有什么建议吗?

MSVC编译的二进制我没有找到反汇编的好方法,所以我在Linux下编译,用GDB反汇编。这是我使用 GDB 反汇编得到的:

-g -fopenmp -lpthread -mavx2 -mfma -O3

/usr/lib/gcc/x86_64-linux-gnu/9/include/avxintrin.h:
898       return *(__m256_u *)__P;
   0x00007fffff710967 <+135>:   vxorps %xmm1,%xmm1,%xmm1
   0x00007fffff71096b <+139>:   lea    0x4(,%r13,4),%r13
   0x00007fffff710973 <+147>:   lea    0x4(,%rdi,%rdi
   0x00007fffff71097b <+155>:   vmovaps %ymm1,%ymm3
   0x00007fffff71097f <+159>:   mov    (%rax),%r10
   0x00007fffff710982 <+162>:   mov    0x10(%r9),%rax
   0x00007fffff710986 <+166>:   lea    0x4(,%rsi,%rsi
   0x00007fffff71098e <+174>:   lea    (%r11,1),%rbx
   0x00007fffff710992 <+178>:   lea    (%r11,%r12
   0x00007fffff710996 <+182>:   lea    (%rdx,%r9
   0x00007fffff71099a <+186>:   add    %r13,%r11
   0x00007fffff71099d <+189>:   add    %rcx,%rsi
   0x00007fffff7109a0 <+192>:   mov    (%rax),%rax
   0x00007fffff7109a3 <+195>:   vmovups (%r10),%xmm7
   0x00007fffff7109a8 <+200>:   vinsertf128 $0x1,0x10(%r10),%ymm7,%ymm0

/home/tianzer/Anime4KCPP/Anime4KCore/src/CPUCNNProcessor.cpp:
390             for (int i = 0; i < 8; i += 2)
=> 0x00007fffff7109af <+207>:   lea    (%rdx,%r10
   0x00007fffff7109b3 <+211>:   add    %r13,%rdx
   0x00007fffff7109b6 <+214>:   add    %rcx,%rdi
   0x00007fffff7109b9 <+217>:   add    %r13,%rcx
   0x00007fffff7109bc <+220>:   lea    0x900(%rax),%r13

/usr/lib/gcc/x86_64-linux-gnu/9/include/avxintrin.h:
735       return (__m256) __builtin_ia32_vbroadcastss256 (__X);
   0x00007fffff7109c3 <+227>:   vbroadcastss -0x4(%rbx),%ymm11
   0x00007fffff7109c9 <+233>:   vmovups (%rax),%xmm5
   0x00007fffff7109cd <+237>:   add    $0x8,%rbx
   0x00007fffff7109d1 <+241>:   add    $0x240,%rax
   0x00007fffff7109d7 <+247>:   vbroadcastss -0x4(%r11),%ymm6
   0x00007fffff7109dd <+253>:   vbroadcastss -0x4(%r9),%ymm8
   0x00007fffff7109e3 <+259>:   add    $0x8,%r12
   0x00007fffff7109e7 <+263>:   add    $0x8,%r11
   0x00007fffff7109eb <+267>:   vbroadcastss -0x4(%rdx),%ymm7
   0x00007fffff7109f1 <+273>:   vbroadcastss -0x4(%rsi),%ymm4
   0x00007fffff7109f7 <+279>:   add    $0x8,%r10
   0x00007fffff7109fb <+283>:   add    $0x8,%r9
   0x00007fffff7109ff <+287>:   vbroadcastss -0xc(%r12),%ymm10
   0x00007fffff710a06 <+294>:   vbroadcastss -0xc(%r10),%ymm9
   0x00007fffff710a0c <+300>:   add    $0x8,%rdx
   0x00007fffff710a10 <+304>:   add    $0x8,%rdi
   0x00007fffff710a14 <+308>:   vbroadcastss -0x4(%rcx),%ymm2
   0x00007fffff710a1a <+314>:   vbroadcastss -0xc(%rdi),%ymm12

/usr/lib/gcc/x86_64-linux-gnu/9/include/fmaintrin.h:
65        return (__m256)__builtin_ia32_vfmaddps256 ((__v8sf)__A,(__v8sf)__B,0x00007fffff710a20 <+320>:   add    $0x8,%rsi
   0x00007fffff710a24 <+324>:   add    $0x8,%rcx
   0x00007fffff710a28 <+328>:   vinsertf128 $0x1,-0x230(%rax),%ymm5,%ymm5
   0x00007fffff710a32 <+338>:   vfmadd231ps %ymm5,%ymm11,%ymm0
   0x00007fffff710a37 <+343>:   vmovups -0x220(%rax),%xmm5
   0x00007fffff710a3f <+351>:   vinsertf128 $0x1,-0x210(%rax),%ymm5
   0x00007fffff710a49 <+361>:   vfmadd231ps %ymm5,%ymm10,%ymm3
   0x00007fffff710a4e <+366>:   vmovups -0x200(%rax),%xmm5
   0x00007fffff710a56 <+374>:   vinsertf128 $0x1,-0x1f0(%rax),%ymm5
   0x00007fffff710a60 <+384>:   vfmadd231ps %ymm5,%ymm6,%ymm1
   0x00007fffff710a65 <+389>:   vmovups -0x1e0(%rax),%xmm6
   0x00007fffff710a6d <+397>:   vinsertf128 $0x1,-0x1d0(%rax),%ymm11
   0x00007fffff710a77 <+407>:   vmovups -0x1c0(%rax),%xmm6
   0x00007fffff710a7f <+415>:   vinsertf128 $0x1,-0x1b0(%rax),%ymm10
   0x00007fffff710a89 <+425>:   vfmadd132ps %ymm11,%ymm0,%ymm9
   0x00007fffff710a8e <+430>:   vfmadd132ps %ymm10,%ymm3,%ymm8
   0x00007fffff710a93 <+435>:   vmovups -0x1a0(%rax),%xmm3
   0x00007fffff710a9b <+443>:   vinsertf128 $0x1,-0x190(%rax),%ymm6
   0x00007fffff710aa5 <+453>:   vfmadd132ps %ymm6,%ymm1,%ymm7
   0x00007fffff710aaa <+458>:   vmovups -0x180(%rax),%xmm1
   0x00007fffff710ab2 <+466>:   vinsertf128 $0x1,-0x170(%rax),%ymm5
   0x00007fffff710abc <+476>:   vmovups -0x160(%rax),%xmm1
   0x00007fffff710ac4 <+484>:   vinsertf128 $0x1,-0x150(%rax),%ymm3
   0x00007fffff710ace <+494>:   vfmadd132ps %ymm5,%ymm9,%ymm12
   0x00007fffff710ad3 <+499>:   vbroadcastss -0x8(%r11),%ymm1
   0x00007fffff710ad9 <+505>:   vbroadcastss -0x8(%r10),%ymm5
   0x00007fffff710adf <+511>:   vfmadd132ps %ymm3,%ymm8,%ymm4
   0x00007fffff710ae4 <+516>:   vbroadcastss -0x8(%r12),%ymm3
   0x00007fffff710aeb <+523>:   vmovaps %ymm12,%ymm11
   0x00007fffff710af0 <+528>:   vmovaps %ymm4,%ymm10
   0x00007fffff710af4 <+532>:   vmovups -0x140(%rax),%xmm4
   0x00007fffff710afc <+540>:   vinsertf128 $0x1,-0x130(%rax),%ymm4,%ymm0
   0x00007fffff710b06 <+550>:   vbroadcastss -0x8(%r9),%ymm4
   0x00007fffff710b0c <+556>:   vfmadd132ps %ymm0,%ymm2
   0x00007fffff710b11 <+561>:   vbroadcastss -0x8(%rbx),%ymm0
   0x00007fffff710b17 <+567>:   vmovaps %ymm2,%ymm6

/usr/lib/gcc/x86_64-linux-gnu/9/include/avxintrin.h:
735       return (__m256) __builtin_ia32_vbroadcastss256 (__X);
   0x00007fffff710b1b <+571>:   vbroadcastss -0x8(%rdx),%ymm2
   0x00007fffff710b21 <+577>:   vbroadcastss -0x8(%rsi),%ymm8
   0x00007fffff710b27 <+583>:   vmovups -0x120(%rax),%xmm13
   0x00007fffff710b2f <+591>:   vmovups -0x100(%rax),%xmm14
   0x00007fffff710b37 <+599>:   vinsertf128 $0x1,-0x110(%rax),%ymm13,%ymm12
   0x00007fffff710b41 <+609>:   vmovups -0xe0(%rax),%xmm15
   0x00007fffff710b49 <+617>:   vbroadcastss -0x8(%rdi),%ymm9
   0x00007fffff710b4f <+623>:   vbroadcastss -0x8(%rcx),%ymm7

/usr/lib/gcc/x86_64-linux-gnu/9/include/fmaintrin.h:
65        return (__m256)__builtin_ia32_vfmaddps256 ((__v8sf)__A,0x00007fffff710b55 <+629>:   vfmadd132ps %ymm12,%ymm0
   0x00007fffff710b5a <+634>:   vinsertf128 $0x1,-0xf0(%rax),%ymm14,%ymm11
   0x00007fffff710b64 <+644>:   vfmadd132ps %ymm11,%ymm3
   0x00007fffff710b69 <+649>:   vinsertf128 $0x1,-0xd0(%rax),%ymm15,%ymm10
   0x00007fffff710b73 <+659>:   vfmadd132ps %ymm10,%ymm1
   0x00007fffff710b78 <+664>:   vmovups -0xc0(%rax),%xmm6
   0x00007fffff710b80 <+672>:   vinsertf128 $0x1,-0xb0(%rax),%ymm6
   0x00007fffff710b8a <+682>:   vfmadd132ps %ymm6,%ymm5
   0x00007fffff710b8f <+687>:   vmovups -0xa0(%rax),%xmm6
   0x00007fffff710b97 <+695>:   vinsertf128 $0x1,-0x90(%rax),%ymm0
   0x00007fffff710ba1 <+705>:   vfmadd132ps %ymm0,%ymm4
   0x00007fffff710ba6 <+710>:   vmovups -0x80(%rax),%xmm3
   0x00007fffff710bab <+715>:   vmovaps %ymm9,%ymm0
   0x00007fffff710baf <+719>:   vinsertf128 $0x1,-0x70(%rax),%ymm6
   0x00007fffff710bb6 <+726>:   vmovups -0x40(%rax),%xmm3
   0x00007fffff710bbb <+731>:   vinsertf128 $0x1,-0x30(%rax),%ymm3
   0x00007fffff710bc2 <+738>:   vfmadd132ps %ymm6,%ymm2
   0x00007fffff710bc7 <+743>:   vmovups -0x60(%rax),%xmm1
   0x00007fffff710bcc <+748>:   vinsertf128 $0x1,-0x50(%rax),%ymm6
   0x00007fffff710bd3 <+755>:   vfmadd132ps %ymm6,%ymm0
   0x00007fffff710bd8 <+760>:   vfmadd132ps %ymm8,%ymm3
   0x00007fffff710bdd <+765>:   vmovups -0x20(%rax),%xmm4
   0x00007fffff710be2 <+770>:   vinsertf128 $0x1,-0x10(%rax),%ymm1
   0x00007fffff710be9 <+777>:   vfmadd132ps %ymm7,%ymm2,%ymm1

/home/tianzer/Anime4KCPP/Anime4KCore/src/CPUCNNProcessor.cpp:
390             for (int i = 0; i < 8; i += 2)
   0x00007fffff710bee <+782>:   cmp    %rax,%r13
   0x00007fffff710bf1 <+785>:   jne    0x7fffff7109c3 <std::_Function_handler<void(int,int,float*,float*),Anime4KCPP::CPU::CNNProcessor::conv8To8(const FP*,const FP*,cv::Mat&)::<lambda(int,Anime4KCPP::CPU::ChanFP,Anime4KCPP::CPU::LineFP)> >::_M_invoke(const std::_Any_data &,int &&,float *&&,float *&&)+227>

/usr/lib/gcc/x86_64-linux-gnu/9/include/avxintrin.h:
1230      return __extension__ (__m256){ 0.0,0.0,0x00007fffff710bf7 <+791>:   vaddps %ymm3,%ymm0
   0x00007fffff710bfb <+795>:   vaddps %ymm1,%ymm0
   0x00007fffff710bff <+799>:   vxorps %xmm1,%xmm1
   0x00007fffff710c03 <+803>:   vmaxps %ymm1,%ymm0

904       *(__m256_u *)__P = __A;
   0x00007fffff710c07 <+807>:   vmovups %xmm0,(%r8)
   0x00007fffff710c0c <+812>:   vextractf128 $0x1,0x10(%r8)
   0x00007fffff710c13 <+819>:   vzeroupper
   0x00007fffff710c16 <+822>:   pop    %rbx
   0x00007fffff710c17 <+823>:   pop    %r12
   0x00007fffff710c19 <+825>:   pop    %r13
   0x00007fffff710c1b <+827>:   pop    %rbp
   0x00007fffff710c1c <+828>:   retq

如果我使用 -march=native 来构建: -g -fopenmp -lpthread -march=native -O3

/usr/lib/gcc/x86_64-linux-gnu/9/include/avxintrin.h:
898       return *(__m256_u *)__P;
   0x00007fffff711596 <+134>:   vxorps %xmm1,%xmm1
   0x00007fffff71159a <+138>:   lea    0x4(,%r10,%r13
   0x00007fffff7115a2 <+146>:   lea    0x4(,%rdi
   0x00007fffff7115aa <+154>:   vmovaps %ymm1,%ymm2
   0x00007fffff7115ae <+158>:   mov    (%rax),%rax
   0x00007fffff7115b1 <+161>:   lea    0x4(,%rsi
   0x00007fffff7115b9 <+169>:   lea    (%r11,%rbx
   0x00007fffff7115bd <+173>:   lea    (%r11,%r12
   0x00007fffff7115c1 <+177>:   lea    (%rdx,%r10
   0x00007fffff7115c5 <+181>:   add    %r13,%r11
   0x00007fffff7115c8 <+184>:   add    %rcx,%rdi
   0x00007fffff7115cb <+187>:   vmovups (%rax),%ymm0

/home/tianzer/Anime4KCPP/Anime4KCore/src/CPUCNNProcessor.cpp:
390             for (int i = 0; i < 8; i += 2)
=> 0x00007fffff7115cf <+191>:   mov    0x10(%r9),%rax
   0x00007fffff7115d3 <+195>:   lea    (%rdx,%r9
   0x00007fffff7115d7 <+199>:   add    %r13,%rdx
   0x00007fffff7115da <+202>:   add    %rcx,%rsi
   0x00007fffff7115dd <+205>:   add    %r13,%rcx
   0x00007fffff7115e0 <+208>:   mov    (%rax),%rax
   0x00007fffff7115e3 <+211>:   lea    0x900(%rax),%r13

/usr/lib/gcc/x86_64-linux-gnu/9/include/avxintrin.h:
735       return (__m256) __builtin_ia32_vbroadcastss256 (__X);
   0x00007fffff7115ea <+218>:   vbroadcastss -0x4(%r11),%ymm4
   0x00007fffff7115f0 <+224>:   vbroadcastss -0x4(%rbx),%ymm3
   0x00007fffff7115f6 <+230>:   add    $0x8,%r12
   0x00007fffff7115fa <+234>:   add    $0x240,%rax
   0x00007fffff711600 <+240>:   vbroadcastss -0x4(%r10),%ymm11
   0x00007fffff711606 <+246>:   vbroadcastss -0x4(%r9),%ymm10
   0x00007fffff71160c <+252>:   add    $0x8,%rbx
   0x00007fffff711610 <+256>:   add    $0x8,%r11
   0x00007fffff711614 <+260>:   vbroadcastss -0x4(%rdx),%ymm9
   0x00007fffff71161a <+266>:   vbroadcastss -0x4(%rdi),%ymm8
   0x00007fffff711620 <+272>:   add    $0x8,%r10
   0x00007fffff711624 <+276>:   add    $0x8,%r9
   0x00007fffff711628 <+280>:   vbroadcastss -0xc(%r12),%ymm5
   0x00007fffff71162f <+287>:   vbroadcastss -0x4(%rsi),%ymm7
   0x00007fffff711635 <+293>:   add    $0x8,%rdx
   0x00007fffff711639 <+297>:   add    $0x8,%rdi
   0x00007fffff71163d <+301>:   vbroadcastss -0x4(%rcx),%ymm6

/usr/lib/gcc/x86_64-linux-gnu/9/include/fmaintrin.h:
65        return (__m256)__builtin_ia32_vfmaddps256 ((__v8sf)__A,0x00007fffff711643 <+307>:   add    $0x8,%rsi
   0x00007fffff711647 <+311>:   add    $0x8,%rcx
   0x00007fffff71164b <+315>:   vfmadd132ps -0x240(%rax),%ymm3
   0x00007fffff711654 <+324>:   vbroadcastss -0x8(%r10),%ymm0
   0x00007fffff71165a <+330>:   vfmadd132ps -0x220(%rax),%ymm5
   0x00007fffff711663 <+339>:   vbroadcastss -0x8(%rsi),%ymm2
   0x00007fffff711669 <+345>:   vfmadd231ps -0x200(%rax),%ymm1
   0x00007fffff711672 <+354>:   vbroadcastss -0x8(%rdx),%ymm4
   0x00007fffff711678 <+360>:   vfmadd132ps -0x1e0(%rax),%ymm11
   0x00007fffff711681 <+369>:   vbroadcastss -0x8(%rcx),%ymm3
   0x00007fffff711687 <+375>:   vfmadd132ps -0x1c0(%rax),%ymm10
   0x00007fffff711690 <+384>:   vbroadcastss -0x8(%r9),%ymm5
   0x00007fffff711696 <+390>:   vfmadd132ps -0x1a0(%rax),%ymm9
   0x00007fffff71169f <+399>:   vbroadcastss -0x8(%rdi),%ymm1
   0x00007fffff7116a5 <+405>:   vfmadd231ps -0x180(%rax),%ymm11
   0x00007fffff7116ae <+414>:   vbroadcastss -0x8(%rbx),%ymm8
   0x00007fffff7116b4 <+420>:   vfmadd231ps -0x160(%rax),%ymm10
   0x00007fffff7116bd <+429>:   vbroadcastss -0x8(%r12),%ymm7
   0x00007fffff7116c4 <+436>:   vfmadd231ps -0x140(%rax),%ymm9

/usr/lib/gcc/x86_64-linux-gnu/9/include/avxintrin.h:
735       return (__m256) __builtin_ia32_vbroadcastss256 (__X);
   0x00007fffff7116cd <+445>:   vbroadcastss -0x8(%r11),0x00007fffff7116d3 <+451>:   vfmadd132ps -0x120(%rax),%ymm8
   0x00007fffff7116dc <+460>:   vfmadd132ps -0x100(%rax),%ymm7
   0x00007fffff7116e5 <+469>:   vfmadd132ps -0xe0(%rax),%ymm6
   0x00007fffff7116ee <+478>:   vfmadd132ps -0xc0(%rax),%ymm0
   0x00007fffff7116f7 <+487>:   vfmadd132ps -0xa0(%rax),%ymm5
   0x00007fffff711700 <+496>:   vfmadd132ps -0x80(%rax),%ymm4
   0x00007fffff711706 <+502>:   vfmadd132ps -0x20(%rax),%ymm3
   0x00007fffff71170c <+508>:   vfmadd231ps -0x60(%rax),%ymm0
   0x00007fffff711712 <+514>:   vfmadd132ps -0x40(%rax),%ymm2
   0x00007fffff711718 <+520>:   vmovaps %ymm3,%ymm1

/home/tianzer/Anime4KCPP/Anime4KCore/src/CPUCNNProcessor.cpp:
390             for (int i = 0; i < 8; i += 2)
   0x00007fffff71171c <+524>:   cmp    %rax,%r13
   0x00007fffff71171f <+527>:   jne    0x7fffff7115ea <std::_Function_handler<void(int,float *&&)+218>

/usr/lib/gcc/x86_64-linux-gnu/9/include/avxintrin.h:
1230      return __extension__ (__m256){ 0.0,0x00007fffff711725 <+533>:   vaddps %ymm2,%ymm0
   0x00007fffff711729 <+537>:   vxorps %xmm1,%xmm1
   0x00007fffff71172d <+541>:   vaddps %ymm3,%ymm0
   0x00007fffff711731 <+545>:   vmaxps %ymm1,%ymm0

904       *(__m256_u *)__P = __A;
   0x00007fffff711735 <+549>:   vmovups %ymm0,(%r8)
   0x00007fffff71173a <+554>:   vzeroupper
   0x00007fffff71173d <+557>:   pop    %rbx
   0x00007fffff71173e <+558>:   pop    %r12
   0x00007fffff711740 <+560>:   pop    %r13
   0x00007fffff711742 <+562>:   pop    %rbp
   0x00007fffff711743 <+563>:   retq

Benchmark 结果来自 Intel i3 4170,分数是处理时间的倒数乘以一个因子,使用 gcc 中的 bin,与上面的反汇编一致。 MSVC的结果几乎一样:

ordinary C++ code: 4.13368
-mavx2 -mfma: 2.51132
-march=native: 2.46779

我注意到在 -march=native 编译下,vfmadd231ps 直接从内存中获取操作数。是不是因为Intel的L2不够大? Ryzen 的每核 L2 是 Intel 的两倍。

解决方法

如果我正确阅读了代码,out0 的第一次计算只需要 _r00_k00,然后 out1 需要 _r01 和 {{1} },等等。然后,对于 _k01,您需要 out0_r03 等。

这是可识别的代码。我想是 GRU 神经网络吧?

无论如何,诀窍是合并内存中的 9 个子矩阵,这样您就只有一个权重矩阵,然后只生成一个输出向量。如果您真的需要将输出分成 3 个向量,您可以在后面的步骤中复制这些值,但这可能不是必需的。而且就算副本是必须的,如果能和激活函数合二为一的话也是相当便宜的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res