LoginSignup
4
1

More than 1 year has passed since last update.

AVX/AVX2による整数比較命令

Last updated at Posted at 2021-12-15

はじめに

整数比較命令について説明します.

整数に対する比較命令で,同一(==)であるか比較するeq命令と,大きい(>)かを比較するgt命令があります.
なお,すべてepiに対する比較命令です.
符号付き整数であるepuに対する比較命令は,AVX512からサポートされています.

_mm256_cmpgt_epi8|16|32 (AVX2)

__m256i _mm256_cmpgt_epi8 (__m256i a, __m256i b)
__m256i _mm256_cmpgt_epi16 (__m256i a, __m256i b)
__m256i _mm256_cmpgt_epi32 (__m256i a, __m256i b)
Instruction: vpcmpgtd ymm, ymm, ymm //epi8
Instruction: vpcmpgtw ymm, ymm, ymm //epi16
Instruction: vpcmpgtd ymm, ymm, ymm //epi32
Architecture Latency Throughput Uops
Alderlake 1 0.5 -
Icelake 1 0.5 1
Skylake 1 0.5 1
Broadwell 1 0.5 1
Haswell 1 0.5 1
Zen3 1 0.25(0.5) 1
Zen2 1 0.33(0.5) 1
Zen 1 0.67(1) 2
  • Zenの()はメモリから呼び出すときのスループットで,遅くなります
  • epi64に対する命令を分けています

cmpgt same same (全て同じレジスタを指定)する場合

Architecture Latency Throughput Uops
Alderlake 0.2 0.02 -
Icelake 0.2 0.22 1
Skylake 0.2 0.25 1
Broadwell 0.3 0.25 1
Haswell 0.3 0.25 1
Zen3 0.2 0.02 1
Zen2 0.3 0.25 1
Zen 0.6 0.5 2
  • 比較の引数が同じ場合は動作が速いです.全て0が出力されます.
  • 誤差等を無視すればxor same sameとほぼ同じ速度と動作です.

説明

8/16/32ビット整数に対する大なりの比較命令です.

dst[i+7:i] := ( a[i+7:i] > b[i+7:i] ) ? 0xFF : 0
dst[i+15:i] := ( a[i+15:i] > b[i+15:i] ) ? 0xFFFF : 0
dst[i+31:i] := ( a[i+31:i] > b[i+31:i] ) ? 0xFFFFFFFF : 0

_mm256_cmpgt_epi64

__m256i _mm256_cmpgt_epi64 (__m256i a, __m256i b)
Instruction: vpcmpgtq ymm, ymm, ymm
Architecture Latency Throughput Uops
Alderlake 3 1 -
Icelake 3 1 1
Skylake 3 1 1
Broadwell 5 1 1
Haswell 5 1 1
Zen3 1 0.25(0.5) 1
Zen2 1 1 1
Zen 2 2 2
  • IntelのCPUは,これだけP5のポートを使うため遅いです.他の命令はP0,P1ポートを使います.
  • AMDのCPUも,使えるポートが通常より少ない(Zen3だけ同じに)

説明

64ビット整数に対する大なりの比較命令です.

dst[i+63:i] := ( a[i+63:i] > b[i+63:i] ) ? 0xFFFFFFFFFFFFFFFF : 0

_mm256_cmpeq_epi8|16|32

__m256i _mm256_cmpeq_epi8 (__m256i a, __m256i b)
__m256i _mm256_cmpeq_epi16 (__m256i a, __m256i b)
__m256i _mm256_cmpeq_epi32 (__m256i a, __m256i b)
Instruction: vpcmpeqb ymm, ymm, ymm //epi8
Instruction: vpcmpeqw ymm, ymm, ymm //epi16
Instruction: vpcmpeqd ymm, ymm, ymm //epi32
Architecture Latency Throughput Uops
Alderlake 1 0.5 -
Icelake 1 0.5 1
Skylake 1 0.5 1
Broadwell 1 0.5 1
Haswell 1 0.5 1
Zen3 1 0.25(0.5) 1
Zen2 1 0.33(0.5) 1
Zen 1 0.67(1) 2

eq same same(全てのビットを1にする命令)

Architecture Latency Throughput Uops
Alderlake 0.2 0.5 -
Icelake 0.2 0.5 1
Skylake 0.5 0.5 1
Broadwell 0.5 0.5 1
Haswell 0.5 0.5 1
Zen3 0.2 0.24 1
Zen2 0.3 0.33 1
Zen 0.7 0.66 2
  • 普通のgtより高速です.
  • eq same sameよりかは遅いです.

説明

8/16/32ビット整数に対する同一比較命令です.

dst[i+7:i] := ( a[i+7:i] == b[i+7:i] ) ? 0xFF : 0
dst[i+15:i] := ( a[i+15:i] == b[i+15:i] ) ? 0xFFFF : 0
dst[i+31:i] := ( a[i+31:i] > b[i+31:i] ) ? 0xFFFFFFFF : 0

_mm256_cmpeq_epi64

__m256i _mm256_cmpeq_epi64 (__m256i a, __m256i b)
Instruction: vpcmpeqq ymm, ymm, ymm
Architecture Latency Throughput Uops
Alderlake 1 0.5 -
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
  • epi64に対する命令は遅いです.

説明

64ビット整数に対する同一比較命令です.

dst[i+63:i] := ( a[i+63:i] == b[i+63:i] ) ? 0xFFFFFFFFFFFFFFFF : 0
4
1
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
4
1