为啥缓存行仅适用于 simdization?
Posted
技术标签:
【中文标题】为啥缓存行仅适用于 simdization?【英文标题】:Why cache line works for simdization only?为什么缓存行仅适用于 simdization? 【发布时间】:2013-10-21 13:28:10 【问题描述】:我正在学习 simd 指令和内存缓存。 我写了一个简单的测试来比较标量和 SIMDized sqrt 计算:
#include <time.h>
#include <iostream>
using namespace std;
#include <cmath>
#include "xmmintrin.h"
#include <stdlib.h>
const int N = 16;
const int NIter = 10000;
float a[N][N] __attribute__((aligned(16)));
float b[N][N] __attribute__((aligned(16)));
float b_simd[N][N] __attribute__((aligned(16)));
int main()
// fill classes by random numbers
for( int i = 0; i < N; i++ )
for( int j = 0; j < N; j++ )
a[i][j] = double(rand())/double(RAND_MAX);
// Scalar
clock_t t = clock();
for( int ii = 0; ii < NIter; ii++ )
for( int i = 0; i < N; i++ )
for( int j = 0; j < N; j++ )
b[i][j] = sqrt(a[i][j]);
double t1 = clock() - t;
t1 /= CLOCKS_PER_SEC;
// SIMD
t = clock();
for( int ii = 0; ii < NIter; ii++ )
for( int i = 0; i < N; i++ )
for( int j = 0; j < N; j += 4 )
__m128 &a2 = reinterpret_cast<__m128&>(a[i][j]);
__m128 &b2 = reinterpret_cast<__m128&>(b_simd[i][j]);
b2 = _mm_sqrt_ps(a2);
double t2 = clock() - t;
t2 /= CLOCKS_PER_SEC;
cout << "Time scalar: " << t1 << " s " << endl;
cout << "Time SIMD: " << t2 << " s, speed up " << t1/t2 << endl;
return 1;
使用给定的代码,我得到:
Time scalar: 0.884565 s
Time SIMD: 0.000264 s, speed up 3350.62
如果我将矩阵大小 N 从 16 更改为 20,则标量和 SIMD 的结果具有可比性:
Time scalar: 1.37275 s
Time SIMD: 0.188165 s, speed up 7.29547
N == 1:
Time scalar: 0.00341 s
16 个浮点数 = 64 个字节正好是一个高速缓存行。因此,a 矩阵的一行适合缓存行,SIMDized 循环的速度提高了 1000 倍,而标量循环没有加速到 N = 1。(N = 1 的标量循环执行大约 16*16 = 比 N=16 快 256 倍,这是在没有缓存行的情况下可以预期的结果。
这怎么可能?
如果有帮助,我已经为 N=16 生成了 asm 代码。 我不知道汇编程序,我在这里看到的所有循环看起来都在 SIMD 中展开,但我不明白为什么这对于产生 1000 倍的差异如此重要。
标量程序:
#include <time.h>
#include <iostream>
using namespace std;
#include <cmath>
#include "xmmintrin.h"
#include <stdlib.h> // rand
const int N = 16; // matrix size.
const int NIter = 1000000;
float a[N][N] __attribute__((aligned(16)));
float b[N][N] __attribute__((aligned(16)));
float b_simd[N][N] __attribute__((aligned(16)));
int main()
for( int ii = 0; ii < NIter; ii++ )
for( int i = 0; i < N; i++ )
for( int j = 0; j < N; j++ )
b[i][j] = sqrt(a[i][j]);
return 1;
给出下一个汇编代码:
.section __TEXT,__text_startup,regular,pure_instructions
.align 4
.globl _main
_main:
LFB1625:
pushq %r13
LCFI0:
movl $1000000, %r13d
pushq %r12
LCFI1:
pushq %rbp
LCFI2:
pushq %rbx
LCFI3:
pushq %rcx
LCFI4:
.align 4
L2:
leaq _a(%rip), %rbx
movl $16, %r12d
leaq _b(%rip), %rbp
.align 4
L35:
sqrtss (%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L39
L3:
movss %xmm0, 0(%rbp)
sqrtss 4(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L40
L5:
movss %xmm0, 4(%rbp)
sqrtss 8(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L41
L7:
movss %xmm0, 8(%rbp)
sqrtss 12(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L42
L9:
movss %xmm0, 12(%rbp)
sqrtss 16(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L43
L11:
movss %xmm0, 16(%rbp)
sqrtss 20(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L44
L13:
movss %xmm0, 20(%rbp)
sqrtss 24(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L45
L15:
movss %xmm0, 24(%rbp)
sqrtss 28(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L46
L17:
movss %xmm0, 28(%rbp)
sqrtss 32(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L47
L19:
movss %xmm0, 32(%rbp)
sqrtss 36(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L48
L21:
movss %xmm0, 36(%rbp)
sqrtss 40(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L49
L23:
movss %xmm0, 40(%rbp)
sqrtss 44(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L50
L25:
movss %xmm0, 44(%rbp)
sqrtss 48(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L51
L27:
movss %xmm0, 48(%rbp)
sqrtss 52(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L52
L29:
movss %xmm0, 52(%rbp)
sqrtss 56(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L53
L31:
movss %xmm0, 56(%rbp)
sqrtss 60(%rbx), %xmm0
ucomiss %xmm0, %xmm0
jp L54
L33:
movss %xmm0, 60(%rbp)
addq $64, %rbx
addq $64, %rbp
subl $1, %r12d
jne L35
subl $1, %r13d
jne L2
popq %rdx
LCFI5:
movl $1, %eax
popq %rbx
LCFI6:
popq %rbp
LCFI7:
popq %r12
LCFI8:
popq %r13
LCFI9:
ret
L54:
LCFI10:
movss 60(%rbx), %xmm0
call _sqrtf
jmp L33
L46:
movss 28(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L17
L45:
movss 24(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L15
L44:
movss 20(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L13
L43:
movss 16(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L11
L42:
movss 12(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L9
L41:
movss 8(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L7
L40:
movss 4(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L5
L39:
movss (%rbx), %xmm0
call _sqrtf
.p2align 4,,4
jmp L3
L50:
movss 44(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L25
L49:
movss 40(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L23
L48:
movss 36(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L21
L47:
movss 32(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L19
L52:
movss 52(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L29
L51:
movss 48(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L27
L53:
movss 56(%rbx), %xmm0
call _sqrtf
.p2align 4,,3
jmp L31
LFE1625:
.align 4
__GLOBAL__sub_I_test.cpp:
LFB1627:
leaq __ZStL8__ioinit(%rip), %rdi
subq $8, %rsp
LCFI11:
call __ZNSt8ios_base4InitC1Ev
movq ___dso_handle@GOTPCREL(%rip), %rdx
leaq __ZStL8__ioinit(%rip), %rsi
movq __ZNSt8ios_base4InitD1Ev@GOTPCREL(%rip), %rdi
addq $8, %rsp
LCFI12:
jmp ___cxa_atexit
LFE1627:
.mod_init_func
.align 3
.quad __GLOBAL__sub_I_test.cpp
.globl _b_simd
.zerofill __DATA,__pu_bss4,_b_simd,1024,4
.globl _b
.zerofill __DATA,__pu_bss4,_b,1024,4
.globl _a
.zerofill __DATA,__pu_bss4,_a,1024,4
.static_data
__ZStL8__ioinit:
.space 1
.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
.set L$set$0,LECIE1-LSCIE1
.long L$set$0
LSCIE1:
.long 0
.byte 0x1
.ascii "zR\0"
.byte 0x1
.byte 0x78
.byte 0x10
.byte 0x1
.byte 0x10
.byte 0xc
.byte 0x7
.byte 0x8
.byte 0x90
.byte 0x1
.align 3
LECIE1:
LSFDE1:
.set L$set$1,LEFDE1-LASFDE1
.long L$set$1
LASFDE1:
.long LASFDE1-EH_frame1
.quad LFB1625-.
.set L$set$2,LFE1625-LFB1625
.quad L$set$2
.byte 0
.byte 0x4
.set L$set$3,LCFI0-LFB1625
.long L$set$3
.byte 0xe
.byte 0x10
.byte 0x8d
.byte 0x2
.byte 0x4
.set L$set$4,LCFI1-LCFI0
.long L$set$4
.byte 0xe
.byte 0x18
.byte 0x8c
.byte 0x3
.byte 0x4
.set L$set$5,LCFI2-LCFI1
.long L$set$5
.byte 0xe
.byte 0x20
.byte 0x86
.byte 0x4
.byte 0x4
.set L$set$6,LCFI3-LCFI2
.long L$set$6
.byte 0xe
.byte 0x28
.byte 0x83
.byte 0x5
.byte 0x4
.set L$set$7,LCFI4-LCFI3
.long L$set$7
.byte 0xe
.byte 0x30
.byte 0x4
.set L$set$8,LCFI5-LCFI4
.long L$set$8
.byte 0xa
.byte 0xe
.byte 0x28
.byte 0x4
.set L$set$9,LCFI6-LCFI5
.long L$set$9
.byte 0xe
.byte 0x20
.byte 0x4
.set L$set$10,LCFI7-LCFI6
.long L$set$10
.byte 0xe
.byte 0x18
.byte 0x4
.set L$set$11,LCFI8-LCFI7
.long L$set$11
.byte 0xe
.byte 0x10
.byte 0x4
.set L$set$12,LCFI9-LCFI8
.long L$set$12
.byte 0xe
.byte 0x8
.byte 0x4
.set L$set$13,LCFI10-LCFI9
.long L$set$13
.byte 0xb
.align 3
LEFDE1:
LSFDE3:
.set L$set$14,LEFDE3-LASFDE3
.long L$set$14
LASFDE3:
.long LASFDE3-EH_frame1
.quad LFB1627-.
.set L$set$15,LFE1627-LFB1627
.quad L$set$15
.byte 0
.byte 0x4
.set L$set$16,LCFI11-LFB1627
.long L$set$16
.byte 0xe
.byte 0x10
.byte 0x4
.set L$set$17,LCFI12-LCFI11
.long L$set$17
.byte 0xe
.byte 0x8
.align 3
LEFDE3:
.constructor
.destructor
.align 1
.subsections_via_symbols
SIMD 程序:
#include <time.h>
#include <iostream>
using namespace std;
#include <cmath>
#include "xmmintrin.h"
#include <stdlib.h> // rand
const int N = 16; // matrix size.
const int NIter = 1000000;
float a[N][N] __attribute__((aligned(16)));
float b[N][N] __attribute__((aligned(16)));
float b_simd[N][N] __attribute__((aligned(16)));
int main()
for( int ii = 0; ii < NIter; ii++ )
for( int i = 0; i < N; i++ )
for( int j = 0; j < N; j += 4 )
__m128 &a2 = reinterpret_cast<__m128&>(a[i][j]);
__m128 &b2 = reinterpret_cast<__m128&>(b_simd[i][j]);
b2 = _mm_sqrt_ps(a2);
return 1;
给出下一个汇编代码:
.section __TEXT,__text_startup,regular,pure_instructions
.align 4
.globl _main
_main:
LFB1625:
subq $672, %rsp
LCFI0:
movl $1000000, %eax
sqrtps 240+_a(%rip), %xmm0
sqrtps _a(%rip), %xmm15
sqrtps 16+_a(%rip), %xmm14
movaps %xmm0, -120(%rsp)
sqrtps 256+_a(%rip), %xmm0
sqrtps 32+_a(%rip), %xmm13
sqrtps 48+_a(%rip), %xmm12
movaps %xmm0, 600(%rsp)
sqrtps 272+_a(%rip), %xmm0
sqrtps 64+_a(%rip), %xmm11
sqrtps 80+_a(%rip), %xmm10
movaps %xmm0, 584(%rsp)
sqrtps 288+_a(%rip), %xmm0
sqrtps 96+_a(%rip), %xmm9
sqrtps 112+_a(%rip), %xmm8
movaps %xmm0, 568(%rsp)
sqrtps 304+_a(%rip), %xmm0
sqrtps 128+_a(%rip), %xmm7
sqrtps 144+_a(%rip), %xmm6
movaps %xmm0, 552(%rsp)
sqrtps 320+_a(%rip), %xmm0
sqrtps 160+_a(%rip), %xmm5
sqrtps 176+_a(%rip), %xmm4
movaps %xmm0, 536(%rsp)
sqrtps 336+_a(%rip), %xmm0
sqrtps 192+_a(%rip), %xmm3
sqrtps 208+_a(%rip), %xmm2
movaps %xmm0, 520(%rsp)
sqrtps 352+_a(%rip), %xmm0
sqrtps 224+_a(%rip), %xmm1
movaps %xmm0, 504(%rsp)
sqrtps 368+_a(%rip), %xmm0
movaps %xmm0, 488(%rsp)
sqrtps 384+_a(%rip), %xmm0
movaps %xmm0, 472(%rsp)
sqrtps 400+_a(%rip), %xmm0
movaps %xmm0, 456(%rsp)
sqrtps 416+_a(%rip), %xmm0
movaps %xmm0, 440(%rsp)
sqrtps 432+_a(%rip), %xmm0
movaps %xmm0, 424(%rsp)
sqrtps 448+_a(%rip), %xmm0
movaps %xmm0, 408(%rsp)
sqrtps 464+_a(%rip), %xmm0
movaps %xmm0, 392(%rsp)
sqrtps 480+_a(%rip), %xmm0
movaps %xmm0, 376(%rsp)
sqrtps 496+_a(%rip), %xmm0
movaps %xmm0, 360(%rsp)
sqrtps 512+_a(%rip), %xmm0
movaps %xmm0, 344(%rsp)
sqrtps 528+_a(%rip), %xmm0
movaps %xmm0, 328(%rsp)
sqrtps 544+_a(%rip), %xmm0
movaps %xmm0, 312(%rsp)
sqrtps 560+_a(%rip), %xmm0
movaps %xmm0, 296(%rsp)
sqrtps 576+_a(%rip), %xmm0
movaps %xmm0, 280(%rsp)
sqrtps 592+_a(%rip), %xmm0
movaps %xmm0, 264(%rsp)
sqrtps 608+_a(%rip), %xmm0
movaps %xmm0, 248(%rsp)
sqrtps 624+_a(%rip), %xmm0
movaps %xmm0, 232(%rsp)
sqrtps 640+_a(%rip), %xmm0
movaps %xmm0, 216(%rsp)
sqrtps 656+_a(%rip), %xmm0
movaps %xmm0, 200(%rsp)
sqrtps 672+_a(%rip), %xmm0
movaps %xmm0, 184(%rsp)
sqrtps 688+_a(%rip), %xmm0
movaps %xmm0, 168(%rsp)
sqrtps 704+_a(%rip), %xmm0
movaps %xmm0, 152(%rsp)
sqrtps 720+_a(%rip), %xmm0
movaps %xmm0, 136(%rsp)
sqrtps 736+_a(%rip), %xmm0
movaps %xmm0, 120(%rsp)
sqrtps 752+_a(%rip), %xmm0
movaps %xmm0, 104(%rsp)
sqrtps 768+_a(%rip), %xmm0
movaps %xmm0, 88(%rsp)
sqrtps 784+_a(%rip), %xmm0
movaps %xmm0, 72(%rsp)
sqrtps 800+_a(%rip), %xmm0
movaps %xmm0, 56(%rsp)
sqrtps 816+_a(%rip), %xmm0
movaps %xmm0, 40(%rsp)
sqrtps 832+_a(%rip), %xmm0
movaps %xmm0, 24(%rsp)
sqrtps 848+_a(%rip), %xmm0
movaps %xmm0, 8(%rsp)
sqrtps 864+_a(%rip), %xmm0
movaps %xmm0, -8(%rsp)
sqrtps 880+_a(%rip), %xmm0
movaps %xmm0, -24(%rsp)
sqrtps 896+_a(%rip), %xmm0
movaps %xmm0, -40(%rsp)
sqrtps 912+_a(%rip), %xmm0
movaps %xmm0, -56(%rsp)
sqrtps 928+_a(%rip), %xmm0
movaps %xmm0, -72(%rsp)
sqrtps 944+_a(%rip), %xmm0
movaps %xmm0, -88(%rsp)
sqrtps 960+_a(%rip), %xmm0
movaps %xmm0, -104(%rsp)
sqrtps 976+_a(%rip), %xmm0
movaps %xmm0, 616(%rsp)
sqrtps 992+_a(%rip), %xmm0
movaps %xmm0, 632(%rsp)
sqrtps 1008+_a(%rip), %xmm0
movaps %xmm0, 648(%rsp)
movaps -120(%rsp), %xmm0
.align 4
L2:
subl $1, %eax
jne L2
movaps %xmm0, 240+_b_simd(%rip)
movaps 600(%rsp), %xmm0
movl $1, %eax
movaps %xmm15, _b_simd(%rip)
movaps %xmm0, 256+_b_simd(%rip)
movaps 584(%rsp), %xmm0
movaps %xmm14, 16+_b_simd(%rip)
movaps %xmm0, 272+_b_simd(%rip)
movaps 568(%rsp), %xmm0
movaps %xmm13, 32+_b_simd(%rip)
movaps %xmm0, 288+_b_simd(%rip)
movaps 552(%rsp), %xmm0
movaps %xmm12, 48+_b_simd(%rip)
movaps %xmm0, 304+_b_simd(%rip)
movaps 536(%rsp), %xmm0
movaps %xmm11, 64+_b_simd(%rip)
movaps %xmm0, 320+_b_simd(%rip)
movaps 520(%rsp), %xmm0
movaps %xmm10, 80+_b_simd(%rip)
movaps %xmm0, 336+_b_simd(%rip)
movaps 504(%rsp), %xmm0
movaps %xmm9, 96+_b_simd(%rip)
movaps %xmm0, 352+_b_simd(%rip)
movaps 488(%rsp), %xmm0
movaps %xmm8, 112+_b_simd(%rip)
movaps %xmm0, 368+_b_simd(%rip)
movaps 472(%rsp), %xmm0
movaps %xmm7, 128+_b_simd(%rip)
movaps %xmm6, 144+_b_simd(%rip)
movaps %xmm5, 160+_b_simd(%rip)
movaps %xmm4, 176+_b_simd(%rip)
movaps %xmm3, 192+_b_simd(%rip)
movaps %xmm2, 208+_b_simd(%rip)
movaps %xmm1, 224+_b_simd(%rip)
movaps %xmm0, 384+_b_simd(%rip)
movaps 456(%rsp), %xmm0
movaps %xmm0, 400+_b_simd(%rip)
movaps 440(%rsp), %xmm0
movaps %xmm0, 416+_b_simd(%rip)
movaps 424(%rsp), %xmm0
movaps %xmm0, 432+_b_simd(%rip)
movaps 408(%rsp), %xmm0
movaps %xmm0, 448+_b_simd(%rip)
movaps 392(%rsp), %xmm0
movaps %xmm0, 464+_b_simd(%rip)
movaps 376(%rsp), %xmm0
movaps %xmm0, 480+_b_simd(%rip)
movaps 360(%rsp), %xmm0
movaps %xmm0, 496+_b_simd(%rip)
movaps 344(%rsp), %xmm0
movaps %xmm0, 512+_b_simd(%rip)
movaps 328(%rsp), %xmm0
movaps %xmm0, 528+_b_simd(%rip)
movaps 312(%rsp), %xmm0
movaps %xmm0, 544+_b_simd(%rip)
movaps 296(%rsp), %xmm0
movaps %xmm0, 560+_b_simd(%rip)
movaps 280(%rsp), %xmm0
movaps %xmm0, 576+_b_simd(%rip)
movaps 264(%rsp), %xmm0
movaps %xmm0, 592+_b_simd(%rip)
movaps 248(%rsp), %xmm0
movaps %xmm0, 608+_b_simd(%rip)
movaps 232(%rsp), %xmm0
movaps %xmm0, 624+_b_simd(%rip)
movaps 216(%rsp), %xmm0
movaps %xmm0, 640+_b_simd(%rip)
movaps 200(%rsp), %xmm0
movaps %xmm0, 656+_b_simd(%rip)
movaps 184(%rsp), %xmm0
movaps %xmm0, 672+_b_simd(%rip)
movaps 168(%rsp), %xmm0
movaps %xmm0, 688+_b_simd(%rip)
movaps 152(%rsp), %xmm0
movaps %xmm0, 704+_b_simd(%rip)
movaps 136(%rsp), %xmm0
movaps %xmm0, 720+_b_simd(%rip)
movaps 120(%rsp), %xmm0
movaps %xmm0, 736+_b_simd(%rip)
movaps 104(%rsp), %xmm0
movaps %xmm0, 752+_b_simd(%rip)
movaps 88(%rsp), %xmm0
movaps %xmm0, 768+_b_simd(%rip)
movaps 72(%rsp), %xmm0
movaps %xmm0, 784+_b_simd(%rip)
movaps 56(%rsp), %xmm0
movaps %xmm0, 800+_b_simd(%rip)
movaps 40(%rsp), %xmm0
movaps %xmm0, 816+_b_simd(%rip)
movaps 24(%rsp), %xmm0
movaps %xmm0, 832+_b_simd(%rip)
movaps 8(%rsp), %xmm0
movaps %xmm0, 848+_b_simd(%rip)
movaps -8(%rsp), %xmm0
movaps %xmm0, 864+_b_simd(%rip)
movaps -24(%rsp), %xmm0
movaps %xmm0, 880+_b_simd(%rip)
movaps -40(%rsp), %xmm0
movaps %xmm0, 896+_b_simd(%rip)
movaps -56(%rsp), %xmm0
movaps %xmm0, 912+_b_simd(%rip)
movaps -72(%rsp), %xmm0
movaps %xmm0, 928+_b_simd(%rip)
movaps -88(%rsp), %xmm0
movaps %xmm0, 944+_b_simd(%rip)
movaps -104(%rsp), %xmm0
movaps %xmm0, 960+_b_simd(%rip)
movaps 616(%rsp), %xmm0
movaps %xmm0, 976+_b_simd(%rip)
movaps 632(%rsp), %xmm0
movaps %xmm0, 992+_b_simd(%rip)
movaps 648(%rsp), %xmm0
movaps %xmm0, 1008+_b_simd(%rip)
addq $672, %rsp
LCFI1:
ret
LFE1625:
.align 4
__GLOBAL__sub_I_test.cpp:
LFB1627:
leaq __ZStL8__ioinit(%rip), %rdi
subq $8, %rsp
LCFI2:
call __ZNSt8ios_base4InitC1Ev
movq ___dso_handle@GOTPCREL(%rip), %rdx
leaq __ZStL8__ioinit(%rip), %rsi
movq __ZNSt8ios_base4InitD1Ev@GOTPCREL(%rip), %rdi
addq $8, %rsp
LCFI3:
jmp ___cxa_atexit
LFE1627:
.mod_init_func
.align 3
.quad __GLOBAL__sub_I_test.cpp
.globl _b_simd
.zerofill __DATA,__pu_bss4,_b_simd,1024,4
.globl _b
.zerofill __DATA,__pu_bss4,_b,1024,4
.globl _a
.zerofill __DATA,__pu_bss4,_a,1024,4
.static_data
__ZStL8__ioinit:
.space 1
.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
.set L$set$0,LECIE1-LSCIE1
.long L$set$0
LSCIE1:
.long 0
.byte 0x1
.ascii "zR\0"
.byte 0x1
.byte 0x78
.byte 0x10
.byte 0x1
.byte 0x10
.byte 0xc
.byte 0x7
.byte 0x8
.byte 0x90
.byte 0x1
.align 3
LECIE1:
LSFDE1:
.set L$set$1,LEFDE1-LASFDE1
.long L$set$1
LASFDE1:
.long LASFDE1-EH_frame1
.quad LFB1625-.
.set L$set$2,LFE1625-LFB1625
.quad L$set$2
.byte 0
.byte 0x4
.set L$set$3,LCFI0-LFB1625
.long L$set$3
.byte 0xe
.byte 0xa8,0x5
.byte 0x4
.set L$set$4,LCFI1-LCFI0
.long L$set$4
.byte 0xe
.byte 0x8
.align 3
LEFDE1:
LSFDE3:
.set L$set$5,LEFDE3-LASFDE3
.long L$set$5
LASFDE3:
.long LASFDE3-EH_frame1
.quad LFB1627-.
.set L$set$6,LFE1627-LFB1627
.quad L$set$6
.byte 0
.byte 0x4
.set L$set$7,LCFI2-LFB1627
.long L$set$7
.byte 0xe
.byte 0x10
.byte 0x4
.set L$set$8,LCFI3-LCFI2
.long L$set$8
.byte 0xe
.byte 0x8
.align 3
LEFDE3:
.constructor
.destructor
.align 1
.subsections_via_symbols
【问题讨论】:
像0.000264
这样的测量似乎很容易受到噪音的影响:例如,我的平台无法可靠地测量小于 1/18 秒的时间。也许您应该增加迭代次数以获得更可靠的测量结果。
N=1
的 SIMD 代码测量值无效:代码假定 N
可以被 4 整除。
anatolyg, 1. 0.2 ms 非噪声,精度为 1 mus,重复测量检查统计误差。但这与我的问题无关——关键是 N=16 的 Time SIMD 非常小。 2.我没有说N=1的Time SIMD有效。
【参考方案1】:
您是否检查过您的编译器实际上是为标量平方根发出一条汇编指令,而不是调用库函数?这可以解释大部分差异,而无需提及内存访问行为。
【讨论】:
如何查看?我在 asm 代码中看到使用了“sqrtss”指令,这是否证明了你的问题?以上是关于为啥缓存行仅适用于 simdization?的主要内容,如果未能解决你的问题,请参考以下文章
为啥启用 NEON SIMDization 时 Android 会崩溃?信号 11 (SIGSEGV),代码 1 (SEGV_MAPERR)
apache_conf .htaccess文件适用于Vanish缓存