9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AVX/AVX2/AVX512Advent Calendar 2021

Day 4

AVX/AVX2による浮動小数点・整数の加算+x87による加算

Last updated at Posted at 2021-12-02

はじめに

SIMDによる浮動小数点,整数の加算の性能について説明します.
浮動小数点の加算はAVX,整数の加算はAVX2で実行できます.

_mm256_add_ps|pd (AVX)

__m256 _mm256_add_ps (__m256 a, __m256 b)
__m256d _mm256_add_pd (__m256d a, __m256d b)
asm: vaddps ymm, ymm, ymm //ps
asm: vaddpd ymm, ymm, ymm //pd

動作
_mm256_add_ps
v2_32.png
_mm256_add_pd
v2_64.png

CPI/Uops

Architecture Latency Throughput Uops
Alderlake 2 0.5 -
Icelake 4 0.5 1
Skylake 4 0.5 1
Broadwell 3 1 1
Haswell 3 1 1
Ivy Bridge 3 1 1
Sandy Bridge 3 1 1
Zen3 3 0.5 1
Zen2 3 0.5 1
Zen 3 1 2
  • SkylakeやIcelakeでは,浮動小数点の加算や乗算,FMAの計算コストは完全に同一です.
  • IntelのCPUではAlderlakeから加算のレイテンシが2になっています.

説明
浮動小数点(float, double)の加算を行います.
float型,double型どちらもパフォーマンスは同じですが,同時に計算する要素数は8つと4つと違い,float型命令のほうが倍のパフォーマンスが出ます.

_mm256_add_epi8|16|32|64 (AVX2)

__m256i _mm256_add_epi8  (__m256i a, __m256i b)
__m256i _mm256_add_epi16 (__m256i a, __m256i b)
__m256i _mm256_add_epi32 (__m256i a, __m256i b)
__m256i _mm256_add_epi64 (__m256i a, __m256i b)
asm: vpaddb ymm, ymm, ymm //epi8
asm: vpaddw ymm, ymm, ymm //epi16
asm: vpaddd ymm, ymm, ymm //epi32
asm: vpaddq ymm, ymm, ymm //epi64

動作
_mm256_add_epi8
v2_8.png
_mm256_add_epi16
v2_16.png
__m256i _mm256_add_epi32
v2_32.png
_mm256_add_epi64
v2_64.png

CPI/Uops

Architecture Latency Throughput Uops
Alderlake 1 0.33 1
Icelake 1 0.33 1
Skylake 1 0.33 1
Broadwell 1 0.5 1
Haswell 1 0.5 1
Zen3 1 0.25 1
Zen2 1 0.33 1
Zen 1 0.67 2
  • Alderlakeの整数加算の速度は,Skylakeから変わっていません.

説明
符号あり整数同士の加算を行います.
オーバーフローのための処理は何もありません.
アセンブリの末尾は,並列処理の単位を示しています.

b:バイト(8),w:ワード(16),d:ダブルワード(32),q:クアッドワード(64)

_mm256_adds_epi|epu8|16 (AVX2)

__m256i _mm256_adds_epi8 (__m256i a, __m256i b)
__m256i _mm256_adds_epu8 (__m256i a, __m256i b)
__m256i _mm256_adds_epi16 (__m256i a, __m256i b)
__m256i _mm256_adds_epu16 (__m256i a, __m256i b)
asm: vpaddsb ymm, ymm, ymm //epi8
asm: vpaddusb ymm, ymm, ymm //epu8
asm: vpaddsw ymm, ymm, ymm //epi16
asm: vpaddusw ymm, ymm, ymm //epu16

動作
_mm256_adds_epi8
v2_8.png
_mm256_adds_epi16
v2_16.png

CPI/Uops

Architecture Latency Throughput Uops
Alderlake 1 0.5 1
Icelake 1 0.5 1
Skylake 1 0.5 1
Broadwell 1 0.5 1
Haswell 1 0.5 1
Zen3 1 0.5 1
Zen2 1 0.5 1
Zen 1 1 2
  • Alderlakeの整数加算の速度は,skylakeから変わっていません.

説明
符号有り・符号無しの飽和付きの加算を行います.飽和演算無しのものより動作は遅いです.
符号有りの場合,127を超えたら127で打ち切ります.
符号無しの場合,255を超えたら255で打ち切ります.

d = max(a + b, 127);
d = max(a + b, 255);

x87による加算

古の浮動小数点回路によるx87を用いた加算のパフォーマンスです.32ビットでも64ビットでもない80ビットが計算できます.
まだ一応,生きています.
なお,SIMDとは違って,1つの要素しか計算できないことに注意してください.
使い方は下記を参照してください.

x87 instruction setを使う
long doubleの話

なお,asmを簡単にはコールできないVisual Studioだとx87の演算器を使うのはかなり手間です.
また,x87使うくらいならdoubledouble演算ができるような疑似4倍精度ライブラリや精度補償計算ライブラリを使うほうが,SIMD演算使っていることや,レジスタの受け渡しの関係で,x87よりもどうやっても速くなる&精度も高いのでそちらを使うことがおすすめです.

kv - C++による精度保証付き数値計算ライブラリ
DD-AVX Library

Architecture Latency Throughput Uops
Alderlake 3 1 -
Icelake 3 1 -
Skylake 3 1 -
Broadwell 3 1 -
Haswell 3 1 -
Ivy Bridge 3 1 -
Sandy Bridge 3 1 -
Zen3 5 1 -
Zen2 5 1 -
Zen 5 1 -
  • uOpsには情報が無かったため,AIDA64のところからひとつづつピックアップ.
9
2
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
9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?