Intel 处理器上的 SIMD 前缀和
简介
前缀和算法查找累积和给定数组的。该操作在各种计算问题中都会遇到,并且需要高性能才能高效处理。在本文中,我们将讨论 Intel CPU 上的 SIMD 指令是否可以增强前缀和算法的性能。
使用 SIMD 的并行前缀和
一种并行前缀和算法涉及分两次执行操作。在第一遍中,并行计算部分和,然后累加每个部分和的总和。第二遍将每个部分和的总和添加到下一个部分和中。通过 OpenMP 使用多线程实现并行性,并在第二遍使用 SIMD 指令可以提高效率。
SIMD 前缀和的代码
以下是 SIMD 前缀和的代码示例多于算法:
__m128 scan_SSE(__m128 x) { x = _mm_add_ps(x, _mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(x), 4))); x = _mm_add_ps(x, _mm_shuffle_ps(_mm_setzero_ps(), x, 0x40)); return x; } void pass1_SSE(float *a, float *s, const int n) { __m128 offset = _mm_setzero_ps(); #pragma omp for schedule(static) nowait for (int i = 0; i < n / 4; i++) { __m128 x = _mm_load_ps(&a[4 * i]); __m128 out = scan_SSE(x); out = _mm_add_ps(out, offset); _mm_store_ps(&s[4 * i], out); offset = _mm_shuffle_ps(out, out, _MM_SHUFFLE(3, 3, 3, 3)); } float tmp[4]; _mm_store_ps(tmp, offset); return tmp[3]; } void pass2_SSE(float *s, __m128 offset, const int n) { #pragma omp for schedule(static) for (int i = 0; i<n/4; i++) { __m128 tmp1 = _mm_load_ps(&s[4 * i]); tmp1 = _mm_add_ps(tmp1, offset); _mm_store_ps(&s[4 * i], tmp1); } }
讨论
这些优化可以显着提高大型数组上的前缀和运算的性能。对两个通道使用 SIMD 进一步提高了效率,减少了计算时间。提供的代码在第二遍中使用 SIMD,并在四核系统上实现了大约 7 倍的性能提升。
以上是Intel CPU 上的 SIMD 指令能否显着提高前缀和算法性能?的详细内容。更多信息请关注PHP中文网其他相关文章!