sse2浮点乘法

时间:2012-03-26 20:12:07

标签: c performance sse2 fann

我尝试将一些代码从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];

1 个答案:

答案 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>