「C/C++ SIMD命令を使う」の編集履歴(バックアップ)一覧はこちら
「C/C++ SIMD命令を使う」(2012/06/15 (金) 20:14:22) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
* SIMD命令を使う
** SIMD命令とは
通常、数値の計算に + や - を使うと、一回の操作でひとつのデータを処理します。複数個のデータを処理する場合にはそれをループさせたりいくつか連続して記述したりします。
普通に考えたらそうするしかないのですが、例えば扱うデータの量が増えてくると、当然そのデータの数だけ計算する回数が増えますよね。で、それを高速化する方法のひとつとしてSIMD命令と言うのが存在します。
SIMD命令とは、Single Instruction Multiple Data、つまりひとつの命令で複数のデータを一度に取り扱うという命令です。シムドと読む人が多いらしいです。
複数のデータを一回で計算する、というとイメージが湧きにくい人もいるかと思います。まずはSIMDを使わずに複数のデータを一回で計算する簡単な例を上げてみましょう。
例:1+2、3+4、5+6、7+8の4つを一回で計算する
|+の左側の値を2桁ずつ並べてひとつの値にします|CENTER:01,03,05,07&br()↓&br()01030507|
|+の右側の値も2桁ずつ並べてひとつの値にします|CENTER:02,04,06,08&br()↓&br()02040608|
|その二つの値を足し合わせます|CENTER:01030507 + 02040608&br()↓&br()03071115|
|計算結果を2桁ずつ取り出します|CENTER:03071115&br()↓&br()03,07,11,15|
正解は1+2=3、3+4=7、5+6=11、7+8=15です。上の計算でも、取り出した値は3、7、11、15になっていますね。なんとなーくイメージできましたでしょうか? この計算では並び方が大事です。手順を見るとデータを並べる手間、取り出す手間があります。プログラミングならデータを右側と左側に分けた二つの配列を用意し、ひとつの数値としてキャストしてから計算することになります。
#highlight(){{
char A[4] = {1, 3, 5, 7};
char B[4] = {2, 4, 6, 8};
char C[4];
*(unsigned int*)&C = *(unsigned int*)&A + *(unsigned int*)&B;}}
※この例では次のバイトへの桁上がりを考慮していません。
さて、上記の例とは仕組みは違いますが、このように複数のデータを1つの大きなデータとみなしてCPUに送り、1回で計算してもらうための命令がSIMD命令です。
CPUには受け取ったデータの1バイト目を担当する人、2バイト目を担当する人といったように複数の演算ユニットがあります。SIMD命令を使うと、まとめられたデータを小分けにしてそれぞれの担当者が同時に計算を行います。
使えるSIMD命令はCPUによって異なります。
* SIMD命令を使う
** SIMD命令とは
通常、数値の計算に + や - を使うと、一回の操作でひとつのデータを処理します。複数個のデータを処理する場合にはそれをループさせたりいくつか連続して記述したりします。
普通に考えたらそうするしかないのですが、例えば扱うデータの量が増えてくると、当然そのデータの数だけ計算する回数が増えますよね。で、それを高速化する方法のひとつとしてSIMD命令と言うのが存在します。
SIMD命令とは、Single Instruction Multiple Data、つまりひとつの命令で複数のデータを一度に取り扱うという命令です。シムドと読む人が多いらしいです。
複数のデータを一回で計算する、というとイメージが湧きにくい人もいるかと思います。まずはSIMDを使わずに複数のデータを一回で計算する簡単な例を上げてみましょう。
例:1+2、3+4、5+6、7+8の4つを一回で計算する
|+の左側の値を2桁ずつ並べてひとつの値にします|CENTER:01,03,05,07&br()↓&br()01030507|
|+の右側の値も2桁ずつ並べてひとつの値にします|CENTER:02,04,06,08&br()↓&br()02040608|
|その二つの値を足し合わせます|CENTER:01030507 + 02040608&br()↓&br()03071115|
|計算結果を2桁ずつ取り出します|CENTER:03071115&br()↓&br()03,07,11,15|
正解は1+2=3、3+4=7、5+6=11、7+8=15です。上の計算でも、取り出した値は3、7、11、15になっていますね。なんとなーくイメージできましたでしょうか? この計算では並び方が大事です。手順を見るとデータを並べる手間、取り出す手間があります。プログラミングならデータを右側と左側に分けた二つの配列を用意し、ひとつの数値としてキャストしてから計算することになります。
#highlight(){{
char A[4] = {1, 3, 5, 7};
char B[4] = {2, 4, 6, 8};
char C[4];
*(unsigned int*)&C = *(unsigned int*)&A + *(unsigned int*)&B;
}}
※この例では次のバイトへの桁上がりを考慮していません。
さて、上記の例とは仕組みは違いますが、このように複数のデータを1つの大きなデータとみなしてCPUに送り、1回で計算してもらうための命令がSIMD命令です。
CPUには受け取ったデータの1バイト目を担当する人、2バイト目を担当する人といったように複数の演算ユニットがあります。SIMD命令を使うと、まとめられたデータを小分けにしてそれぞれの担当者が同時に計算を行います。
使えるSIMD命令はCPUによって異なります。
表示オプション
横に並べて表示:
変化行の前後のみ表示: