LoginSignup
11
11

More than 5 years have passed since last update.

Intrinsicsを使ってもっと早く演算やってみよう!

Last updated at Posted at 2016-09-01

始めます。

こんにちは。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が必要です。

C/C++
#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個のデータを使えます。

C/C++
 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個持っています。

C/C++
__m128i xmmA = _mm_load_si128((__m128i*)aData);
__m128i xmmB = _mm_load_si128((__m128i*)bData);

足し算と引き算やってみよう!

上まで、問題なかったですか? :laughing:
もし、問題あったらこの内容は進めません。
さあ。。本格的な基本演算始めます。

-足し算。

C/C++

__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]);


-引き算。

C/C++

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 を押しと結果が出ます。 :tada:

掛け算やってみよう!

あれ?掛け算しかない?割り算は?と思いましたか?
*はい!Intrinsicは割り算の命令語ないです。 :sob: *

残念ですね。。でも、方法はあります。次のPOSTで載せてみます。

-掛け算

C/C++

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 を押しと結果が出ます。 :tada:

結果

まず、今日は割り算を除外した、足し算、引き算、
最後に掛け算までやってみました。
どうでしたか? Intrinsicは基本Serial演算より1.5~2倍は早くなります。

読みいただきありがとうございました。
次のPostで会いましょう!

Dreamwalker。

11
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11