#始めます。
こんにちは。Dreamwalkerです。
intrinsicを使って基本的な演算やってみました。
これを使ったら、基本Serial演算より早いです。
#開発環境
- XCODE 7.3.1 ( Visual Studio 2013をお勧めします。。)
- C/C++
- OS : macos
- Data Unit : 16bit Short
#使ったHeader ..
MMXを始め今はAVX2まで、開発進めています。
私はSSE2を基本のSIMDで使いました。
#まずHeaderから。。
intrinsicを使うためにはHeaderが必要です。
#include <emmintrin.h> //SSE2
###他のHeaderはこれを参考してください。
普通Ver upしていくと、下のversionを含めています。
例えば、AVX Headerを使ったらMMX~SSE4.2までの命令を使えます。
Header | intrinsic |
---|---|
mmintrin.h | MMX |
xmmintrin.h | SSE2 |
emmintrin.h | SSE3 |
pmmintrin.h | SSE3 |
tmmintrin.h | SSSE3 |
smmintrin.h | SSE4.1 |
nmmintrin.h | SSE4.2 |
ammintrin.h | SSE4A |
wmmintrin.h | AES |
immintrin.h | AVX |
zmmintrin.h | AVX512 |
#メイン関数の中で、配列を作ろう!
SSEからのレジスターは128Bitです。
shortを使ったら128bit中で8個のデータを使えます。
short aData[8] = {2,3,4,5,6,7,5,3};
short bData[8] = {1,2,3,4,5,6,7,8};
short Result[8] = {0};
#配列をXMMレジスターへLoadしよう。
###この過程しなければならないです。
XmmレジスターはCPU中(Coreの中)で、あるSIMDレジスターで128bit Sizeです。
Xmm0~Xmm7まで、Core別々8個持っています。
__m128i xmmA = _mm_load_si128((__m128i*)aData);
__m128i xmmB = _mm_load_si128((__m128i*)bData);
#足し算と引き算やってみよう!
上まで、問題なかったですか?
もし、問題あったらこの内容は進めません。
さあ。。本格的な基本演算始めます。
-足し算。
__m128i xmmR = _mm_add_epi16(xmmA, xmmB); // xmmA + xmmB
_mm_store_si128((__m128i*)Result, xmmR);
printf("ADD: %d,%d,%d,%d,%d,%d,%d,%d\n",Result[7],Result[6],
Result[5],Result[4],Result[3],Result[2],Result[1],Result[0]);
-引き算。
xmmR = _mm_sub_epi16(xmmA, xmmB); // xmmA - xmmB
_mm_store_si128((__m128i*)R, xmmR);
printf("SUB: %d,%d,%d,%d,%d,%d,%d,%d\n",Result[7],Result[6],
Result[5],Result[4],Result[3],Result[2],Result[1],Result[0]);
Xcodeで Command + R を押しと結果が出ます。
#掛け算やってみよう!
あれ?掛け算しかない?割り算は?と思いましたか?
**はい!Intrinsicは割り算の命令語ないです。 **
残念ですね。。でも、**方法はあります。**次のPOSTで載せてみます。
-掛け算
xmmR = _mm_mullo_epi16(xmmA, xmmB); // xmmA * xmmB
_mm_store_si128((__m128i*)R, xmmR);
printf("MUL: %d,%d,%d,%d,%d,%d,%d,%d\n",Result[7],Result[6],
Result[5],Result[4],Result[3],Result[2],Result[1],Result[0]);
mulloはlow 16bitだけ生き残します。
天才な皆様はmulhiもあるでしょ!と思えます。
Xcodeで Command + R を押しと結果が出ます。
#結果
まず、今日は割り算を除外した、足し算、引き算、
最後に掛け算までやってみました。
どうでしたか? Intrinsicは基本Serial演算より1.5~2倍は早くなります。
読みいただきありがとうございました。
次のPostで会いましょう!
Dreamwalker。