はじめに
整数比較命令について説明します.
整数に対する比較命令で,同一(==)であるか比較する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