C++快速添加2个数组

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的最快方法是什么? 循环很慢!

Pau*_*l R 8

这是一个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.