Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

始めます。

こんにちは。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。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした