組み込みアルゴリズム移植最適化研究ノート2-SIMDプログラミング(単一の命令ストリームと複数のデータストリーム)
1.SIMDの概念
単一命令複数データ、つまり、単一命令ストリームと複数データストリームは、複数のデータストリームに対して同じ操作を実行します。単一命令、複数データ(SIMD)は、並列コンピューターの一種です(Flynn分類による)。複数のデータポイントで同じ操作を同時に(同時に)実行できる複数の処理要素を備えたコンピューターについて説明します。この種のマシンは、データレベルの並列処理(並行性ではない)を利用します。特定の時点では、命令は1つだけですが、複数の同時(同時)計算、つまり並列計算があります。SIMDは、デジタル画像のコントラストの調整やデジタルオーディオの音量の調整など、いくつかの一般的なタスクに特に適しています。最新のCPU設計には、マルチメディア使用のパフォーマンスを向上させるためのSIMD命令が含まれています。SIMDとSIMTを混同しないでください。前者はデータレベルで機能し、後者はスレッドを使用します。簡単な例は、ベクトルの加算と減算です。
MIMDとの違い
SIMDには単一のグローバルコントロールユニットがありますが、後者には複数のコントロールユニット+処理要素があります。
第二に、SIMDの適用
- 画像処理
- オーディオ
- 科学計算
- データベースのデータ並列コンピューティング。
SIMDを適用するタイミング
- 通常のデータアクセスモード:データはメモリに継続的に保存されます。
- 短いデータ型
- ストリーミングデータ処理
..。
3つ目は、SIMDを使用することの長所と短所です。
利点
- 並行性が高くなります。
- 設計は比較的単純です(MIMDと比較する必要があり、機能ユニットを繰り返すだけで済みます)。
チップサイズが小さいです。
不利益
- プログラマーは、開発時にハードウェアに明示的に連絡する必要があります。
第四に、SIMD並列処理の問題
SIMD並列開発では、複数の同一の算術演算を1つのSIMD演算に簡略化できます。複数のフェッチ/保存結果演算を、より広いメモリの1つの演算に変えることができます(メモリが連続している必要がある場合)。
5、SIMDプログラミングの複雑さ
低レベルのプログラミング要件:
- データを整列させる必要があります。
- データは連続領域に保存されます。
- 制御フローの問題により、複雑さが増す可能性があります。
6、SIMD開発
いわゆるSIMD命令は、単一命令の複数データ、つまり単一命令の複数データ操作を指し、その目的は、CPUがデータの並列処理を実現し、操作効率を向上させるのを支援することです。
MMX
MMXは、57個の命令で構成されるSIMDマルチメディア命令セットです。MMXは64ビットレジスタを2個の32ビットまたは8個の8ビットレジスタとして扱い、シェーピング計算のみを処理できます。このような64ビットレジスタには8つのグループがあり、個別に名前が付けられています。 MM0〜MM7です。これらのレジスタはMMX用に個別に設定されていませんが、借用されたFPUレジスタは、演算用の浮動小数点レジスタを占有します(64ビットMMXレジスタは、実際には浮動小数点レジスタのエイリアスです)。そのため、MMX命令と浮動小数点演算は次の場所では機能しません。同時に。MMXと浮動小数点モードの切り替えにかかる時間を短縮するために、プログラマーはモード切り替えの数を可能な限り削減しようとします。つまり、これら2つの操作はアプリケーションで相互に排他的です。
SSE
SSEのフルネームはストリーミングSIMD拡張命令で、MMXに基づいて開発されたSIMD命令セットです。フローティングポイントレジスタを占有しなくなりましたが、別個の128ビットXMMレジスタを使用します。これに基づいて、SSE2 / SSE3 / SSE4命令セットが開発されました。SSE2はさらに倍精度浮動小数点数をサポートします。レジスタ長は変更されないため、2つの倍精度浮動小数点計算または4つの単精度浮動小数点計算しかサポートできません。さらに、これに整数計算を実装します。レジスタのセット。、したがって、MMXを置き換えます。SSE3は、より複雑な算術計算をサポートしています。SSE4はさらに命令を追加し、データ移動に懸命に取り組み、整列されていないデータ移動をサポートし、スーパーシャッフルエンジンを追加します。
AVX
SSE命令セットに基づいて、128ビットXMMレジスタが256ビットYMMレジスタに拡張され、256ビットベクトル計算がサポートされます。AVXは、下位のSSE / SSE2 / SSE3 / SSE4と完全に互換性があります。 YMMレジスタの128ビットはXMMレジスタです。
3DNow!
3DNow!は、Intel MMXレジスタの論理拡張です。MMXは並列整数演算のみを提供し、3DNow!は並列浮動小数点演算を実装します。3DNow!は、既存のMMX命令セットに基づいて、MMXに必要なコンテキスト変換を必要とせずに、整数コードと浮動小数点コードを使用した混合演算を実現できます。
7つの関連するコード例
CPUでサポートされているSIMD命令セットを表示する
cat /proc/cpuinfo
コンパイラでサポートされているSIMD命令セットを確認できます
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts nopl xtopology tsc_reliable nonstop_tsc aperfmperf eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid rdseed adx smap xsaveopt dtherm ida arat pln pts hwp hwp_notify hwp_act_window hwp_epp
GCCプロセッサでサポートされているSIMD命令セットを表示する
gcc -march=native -c -Q --help=target
サポートされているSIMD命令セットとサポートされていないSIMD命令セットを確認できます。
diyun@diyun-virtual-machine:~/桌面$ gcc -march=native -c -Q --help=target
The following options are target specific:
-m128bit-long-double [disabled]
-m32 [disabled]
-m3dnow [disabled]
-m3dnowa [disabled]
-m64 [enabled]
-m80387 [enabled]
-m8bit-idiv [disabled]
-m96bit-long-double [enabled]
-mabi= sysv
-mabm [enabled]
-maccumulate-outgoing-args [disabled]
-maddress-mode= short
-madx [enabled]
-maes [enabled]
-malign-double [disabled]
-malign-functions= 0
-malign-jumps= 0
-malign-loops= 0
-malign-stringops [enabled]
-mandroid [disabled]
-march= core-avx2
-masm= att
-mavx [enabled]
-mavx2 [enabled]
-mavx256-split-unaligned-load [disabled]
-mavx256-split-unaligned-store [disabled]
-mbionic [disabled]
-mbmi [enabled]
-mbmi2 [enabled]
-mbranch-cost= 0
-mcld [disabled]
-mcmodel= 32
-mcpu=
-mcrc32 [disabled]
-mcx16 [enabled]
-mdispatch-scheduler [disabled]
-mf16c [enabled]
-mfancy-math-387 [enabled]
-mfentry [enabled]
-mfma [enabled]
-mfma4 [disabled]
-mforce-drap [disabled]
-mfp-ret-in-387 [enabled]
-mfpmath= 387
-mfsgsbase [enabled]
-mfunction-return= keep
-mfused-madd
-mfxsr [enabled]
-mglibc [enabled]
-mhard-float [enabled]
-mhle [disabled]
-mieee-fp [enabled]
-mincoming-stack-boundary= 0
-mindirect-branch-register [disabled]
-mindirect-branch= keep
-minline-all-stringops [disabled]
-minline-stringops-dynamically [disabled]
-mintel-syntax
-mlarge-data-threshold= 0x10000
-mlong-double-64 [disabled]
-mlong-double-80 [enabled]
-mlwp [disabled]
-mlzcnt [enabled]
-mmmx [disabled]
-mmovbe [enabled]
-mms-bitfields [disabled]
-mno-align-stringops [disabled]
-mno-fancy-math-387 [disabled]
-mno-push-args [disabled]
-mno-red-zone [disabled]
-mno-sse4 [disabled]
-momit-leaf-frame-pointer [disabled]
-mpc32 [disabled]
-mpc64 [disabled]
-mpc80 [disabled]
-mpclmul [enabled]
-mpopcnt [enabled]
-mprefer-avx128 [disabled]
-mpreferred-stack-boundary= 0
-mprfchw [enabled]
-mpush-args [enabled]
-mrdrnd [enabled]
-mrdseed [enabled]
-mrecip [disabled]
-mrecip=
-mred-zone [enabled]
-mregparm= 0
-mrtd [disabled]
-mrtm [disabled]
-msahf [enabled]
-msoft-float [disabled]
-msse [enabled]
-msse2 [enabled]
-msse2avx [disabled]
-msse3 [enabled]
-msse4 [enabled]
-msse4.1 [enabled]
-msse4.2 [enabled]
-msse4a [disabled]
-msse5
-msseregparm [disabled]
-mssse3 [enabled]
-mstack-arg-probe [disabled]
-mstackrealign [enabled]
-mstringop-strategy= [default]
-mtbm [disabled]
-mtls-dialect= gnu
-mtls-direct-seg-refs [enabled]
-mtune= generic
-muclibc [disabled]
-mveclibabi= [default]
-mvect8-ret-in-mem [disabled]
-mvzeroupper [disabled]
-mx32 [disabled]
-mxop [disabled]
-mxsave [enabled]
-mxsaveopt [enabled]
Known assembler dialects (for use with the -masm-dialect= option):
att intel
Known ABIs (for use with the -mabi= option):
ms sysv
Known code models (for use with the -mcmodel= option):
32 kernel large medium small
Valid arguments to -mfpmath=:
387 387+sse 387,sse both sse sse+387 sse,387
Known indirect branch choices (for use with the -mindirect-branch=/-mfunction-return= options):
keep thunk thunk-extern thunk-inline
Known vectorization library ABIs (for use with the -mveclibabi= option):
acml svml
Known address mode (for use with the -maddress-mode= option):
long short
Valid arguments to -mstringop-strategy=:
byte_loop libcall loop rep_4byte rep_8byte rep_byte unrolled_loop
Known TLS dialects (for use with the -mtls-dialect= option):
gnu gnu2
SIMD命令の使用例
単純な浮動小数点行列の乗算(コンパイラーの最適化)
float_matrix_mutiply.c:
#include <stdio.h>
#include <stdio.h>
void printf_matrix(int x,int y,double a[x][y])
{
for(int i=0;i<x;i++){
for(int j=0;j<y;j++){
printf("%lf ",a[i][j]);
}
printf("\n");
}
}
int main()
{
int M=2,N=3,P=4;
double matrix1[M][N];
double matrix2[N][P];
FILE *fp1,*fp2;
fp1 = fopen("./matrix1","r");
fp2 = fopen("./matrix2","r");
int i = 0;
while(!feof(fp1)){
fscanf(fp1,"%lf %lf %lf",&matrix1[i][0],&matrix1[i][1],&matrix1[i][2]);
i++;
}
printf("The first matrix is:\n");
printf_matrix(M,N,matrix1);
int j = 0;
while(!feof(fp2)){
fscanf(fp2,"%lf %lf %lf %lf",&matrix2[j][0],&matrix2[j][1],&matrix2[j][2],&matrix2[j][3]);
j++;
}
printf("The second matrix is:\n");
printf_matrix(N,P,matrix2);
double result[M][P];
for(int i=0;i<M;i++){
for(int k=0;k<P;k++){
for(int j=0;j<N;j++){
result[i][k] += matrix1[i][j]*matrix2[j][k];
}
}
}
printf("The matrix mutilpy result is:\n");
printf_matrix(M,P,result);
}
コンパイル:
gcc float_matrix_mutiply.c -o float_matrix_mutiply -msse -mfpmath=sse -march=native
逆コンパイルは、xmmレジスタやmovsdなどのSIMD命令が使用されていることを示しています:
diyun@diyun-virtual-machine:~/桌面/0205_test$ objdump -d float_matrix_mutiply |grep xmm
400725: c5 fb 10 45 c8 vmovsd -0x38(%rbp),%xmm0
400d9a: c5 fb 10 0c d0 vmovsd (%rax,%rdx,8),%xmm1
400dc3: c5 fb 10 14 d0 vmovsd (%rax,%rdx,8),%xmm2
400dec: c5 fb 10 04 d0 vmovsd (%rax,%rdx,8),%xmm0
400df1: c5 eb 59 c0 vmulsd %xmm0,%xmm2,%xmm0
400df5: c5 f3 58 c0 vaddsd %xmm0,%xmm1,%xmm0
400e16: c5 fb 11 04 d0 vmovsd %xmm0,(%rax,%rdx,8)
優先:
1、https://blog.csdn.net/sinat_26210035/article/details/88773961?utm_medium = distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source = distribute.pc_relevant_t0.none-task-ブログ-BlogCommendFromMachineLearnPai2-1.control
3、https://zhuanlan.zhihu.com/p/71266408
4、https://www.cnblogs.com/xidian-wws/p/11023762.html
5、HTTPS://blog.csdn.net/weixin_42826139/記事/詳細/ 86313717