【发布时间】:2011-08-09 10:53:44
【问题描述】:
这是一段 C++ 代码:
#define ARR_SIZE_TEST ( 8 * 1024 * 1024 )
void cpp_tst_add( unsigned* x, unsigned* y )
{
for ( register int i = 0; i < ARR_SIZE_TEST; ++i )
{
x[ i ] = x[ i ] + y[ i ];
}
}
这是一个霓虹灯版本:
void neon_assm_tst_add( unsigned* x, unsigned* y )
{
register unsigned i = ARR_SIZE_TEST >> 2;
__asm__ __volatile__
(
".loop1: \n\t"
"vld1.32 {q0}, [%[x]] \n\t"
"vld1.32 {q1}, [%[y]]! \n\t"
"vadd.i32 q0 ,q0, q1 \n\t"
"vst1.32 {q0}, [%[x]]! \n\t"
"subs %[i], %[i], $1 \n\t"
"bne .loop1 \n\t"
: [x]"+r"(x), [y]"+r"(y), [i]"+r"(i)
:
: "memory"
);
}
测试功能:
void bench_simple_types_test( )
{
unsigned* a = new unsigned [ ARR_SIZE_TEST ];
unsigned* b = new unsigned [ ARR_SIZE_TEST ];
neon_tst_add( a, b );
neon_assm_tst_add( a, b );
}
我已经测试了这两种变体,这里有一份报告:
add, unsigned, C++ : 176 ms
add, unsigned, neon asm : 185 ms // SLOW!!!
我还测试了其他类型:
add, float, C++ : 571 ms
add, float, neon asm : 184 ms // FASTER X3!
问题: 为什么 32 位整数类型的 neon 速度较慢?
我使用了最新版本的 GCC for Android NDK。 NEON 优化标志已打开。 这是一个反汇编的 C++ 版本:
MOVS R3, #0
PUSH {R4}
loc_8
LDR R4, [R0,R3]
LDR R2, [R1,R3]
ADDS R2, R4, R2
STR R2, [R0,R3]
ADDS R3, #4
CMP.W R3, #0x2000000
BNE loc_8
POP {R4}
BX LR
这里是霓虹灯的反汇编版本:
MOV.W R3, #0x200000
.loop1
VLD1.32 {D0-D1}, [R0]
VLD1.32 {D2-D3}, [R1]!
VADD.I32 Q0, Q0, Q1
VST1.32 {D0-D1}, [R0]!
SUBS R3, #1
BNE .loop1
BX LR
这是所有基准测试:
add, char, C++ : 83 ms
add, char, neon asm : 46 ms FASTER x2
add, short, C++ : 114 ms
add, short, neon asm : 92 ms FASTER x1.25
add, unsigned, C++ : 176 ms
add, unsigned, neon asm : 184 ms SLOWER!!!
add, float, C++ : 571 ms
add, float, neon asm : 184 ms FASTER x3
add, double, C++ : 533 ms
add, double, neon asm : 420 ms FASTER x1.25
问题: 为什么 32 位整数类型的 neon 速度较慢?
【问题讨论】:
-
@Cody 这个主题有问题,也许是这样?
-
C++ 对所有整数类型都更快吗?我认为您的程序集并不像您希望的整数类型那样最佳。
-
问题是为什么 neon 在 32 位整数类型中速度较慢?
-
@rubenvb 我已经更新了所有类型的基准报告。
-
对于那些感到困惑的人:NEON 是 ARM 的 SIMD 扩展,允许 128 位操作,即一次 4 个 32 位操作。人们会期望它在所有情况下都比非 SIMD 指令更快。 arm.com/products/processors/technologies/neon.php
标签: c++ arm simd neon cortex-a8