Tom*_*len 7 c++ arrays performance simd micro-optimization
鉴于阵列:
int canvas[10][10];
int addon[10][10];
Run Code Online (Sandbox Code Playgroud)
在所有值都在0到100之间的情况下,C++中添加这两个数组的最快方法是什么,因此画布中的每个单元都等于自身加上插件中相应的单元格值?
IE,我想实现类似的东西:
canvas += another;
Run Code Online (Sandbox Code Playgroud)
因此,如果canvas [0] [0] = 3且addon [0] [0] = 2则canvas [0] [0] = 5
速度是必不可少的,因为我正在编写一个非常简单的程序来暴力背包式问题,并且将有数千万种组合.
并且作为一个额外的小问题(感谢您可以提供帮助!)检查画布中的任何值是否超过100的最快方法是什么? 循环很慢!
这是一个SSE4实现,应该在Nehalem(Core i7)上表现得非常好:
#include <limits.h>
#include <emmintrin.h>
#include <smmintrin.h>
static inline int canvas_add(int canvas[10][10], int addon[10][10])
{
__m128i * cp = (__m128i *)&canvas[0][0];
const __m128i * ap = (__m128i *)&addon[0][0];
const __m128i vlimit = _mm_set1_epi32(100);
__m128i vmax = _mm_set1_epi32(INT_MIN);
__m128i vcmp;
int cmp;
int i;
for (i = 0; i < 10 * 10; i += 4)
{
__m128i vc = _mm_loadu_si128(cp);
__m128i va = _mm_loadu_si128(ap);
vc = _mm_add_epi32(vc, va);
vmax = _mm_max_epi32(vmax, vc); // SSE4 *
_mm_storeu_si128(cp, vc);
cp++;
ap++;
}
vcmp = _mm_cmpgt_epi32(vmax, vlimit); // SSE4 *
cmp = _mm_testz_si128(vcmp, vcmp); // SSE4 *
return cmp == 0;
}
Run Code Online (Sandbox Code Playgroud)
与gcc -msse4.1 ...特定开发环境一起编译或等效.
对于没有SSE4的旧CPU(以及更昂贵的错位负载/存储),您需要(a)使用SSE2/SSE3内在函数的合适组合来替换SSE4操作(标有*上面的内容),理想情况下(b)make确保您的数据是16字节对齐并使用对齐的加载/存储(_mm_load_si128/ _mm_store_si128)代替_mm_loadu_si128/ _mm_storeu_si128.