3

我尝试将 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];
4

1 回答 1

5

为了有机会在这里看到加速,您需要执行以下操作:

  • 确保weights[i]16 字节对齐,然后使用_mm_load_ps而不是_mm_loadu_ps
  • 重新组织neurons[],使其成为 SoA 而不是 AoS(也是 16 字节对齐),然后用于_mm_load_ps一次加载 4 个值
  • 将水平和移出循环(有一个循环,对吗?) - 只需将 4 个部分和保留在一个向量中vneurom_sum,然后在循环之后对该向量进行一个最终水平和

即使那样,您也不会看到巨大的加速,因为您只对 2 次加载和 1 次存储进行一次算术运算。由于大多数现代 x86 CPU 无论如何都有两个标量 FPU,因此您可能不会接近 128 位浮点 SIMD 的理论 4 倍加速,我预计相对于标量代码的速度不会超过 50%。

于 2012-03-26T20:37:55.947 回答