Nehalem (Core i7) でかなりうまく機能するはずの SSE4 実装を次に示します。
#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;
}
gcc -msse4.1 ...
特定の開発環境で、または同等のものをコンパイルします。
SSE4 を使用しない古い CPU (およびはるかにコストのかかるミスアラインされたロード/ストアがある) の場合、(a) SSE2/SSE3 組み込み関数の適切な組み合わせを使用して SSE4 操作 (*
上記のマークが付いている) を置き換える必要があり、理想的には (b) makeデータが 16 バイト アラインされていることを確認し、アラインされたロード/ストア ( _mm_load_si128
/ _mm_store_si128
) を_mm_loadu_si128
/の代わりに使用します_mm_storeu_si128
。