我尝试将一些代码从FANN Lib(用C编写的神经网络)移植到SSE2。 但是SSE2的性能比普通代码差。使用我的SSE2实现运行一次运行需要5.50分钟而不需要5.20分钟。
SSE2如何比正常运行慢?可能是因为_mm_set_ps
?我使用Apple LLVM编译器(XCode 4)编译代码(所有SSE扩展标志都打开,优化级别为-Os
)。
没有SSE2的代码
neuron_sum +=
fann_mult(weights[i], neurons[i].value) +
fann_mult(weights[i + 1], neurons[i + 1].value) +
fann_mult(weights[i + 2], neurons[i + 2].value) +
fann_mult(weights[i + 3], neurons[i + 3].value);
SSE2代码
__m128 a_line=_mm_loadu_ps(&weights[i]);
__m128 b_line=_mm_set_ps(neurons[i+3].value,neurons[i+2].value,neurons[i+1].value,neurons[i].value);
__m128 c_line=_mm_mul_ps(a_line, b_line);
neuron_sum+=c_line[0]+c_line[1]+c_line[2]+c_line[3];
答案 0 :(得分:5)
要想有机会在这里看到加速,您需要执行以下操作:
weights[i]
对齐16个字符,然后使用_mm_load_ps
代替_mm_loadu_ps
neurons[]
以便它是SoA而不是AoS(也是16字节对齐),然后使用_mm_load_ps
一次加载4个值vneurom_sum
中保留4个部分和,然后在循环后对此向量进行最后一个水平求和即使这样,你也不会看到巨大的加速,因为你只对2个负载和1个存储进行一次算术运算。由于大多数现代x86 CPU都有两个标量FPU,你可能无法接近128位浮点SIMD的理论4倍加速,我估计相对于标量代码加速不超过50%。 / p>