Test different SIMD functionality units with an input/output buffer. CpuFlag parameter indicates SIMD routine to be tested: CpuInfo::SSSE3 for ByteSwapSSE_Unit; CpuInfo::AVX2 for ByteSwapAVX2_Unit;
| 133 | // CpuInfo::SSSE3 for ByteSwapSSE_Unit; |
| 134 | // CpuInfo::AVX2 for ByteSwapAVX2_Unit; |
| 135 | void TestByteSwapSimd_Unit(const int64_t CpuFlag) { |
| 136 | void (*bswap_fptr)(const uint8_t* src, uint8_t* dst) = NULL; |
| 137 | int buf_size = 0; |
| 138 | if (IS_AARCH64 || CpuFlag == CpuInfo::SSSE3) { |
| 139 | buf_size = 16; |
| 140 | bswap_fptr = SimdByteSwap::ByteSwap128; |
| 141 | } else { |
| 142 | static const int64_t AVX2_MASK = CpuInfo::AVX2; |
| 143 | ASSERT_EQ(CpuFlag, AVX2_MASK); |
| 144 | buf_size = 32; |
| 145 | bswap_fptr = SimdByteSwap::ByteSwap256; |
| 146 | } |
| 147 | |
| 148 | DCHECK(bswap_fptr != NULL); |
| 149 | // IMPALA-4058: test that bswap_fptr works when it reads to o writes from memory with |
| 150 | // any alignment. |
| 151 | static const size_t MAX_ALIGNMENT = 64; |
| 152 | uint8_t src_buf[buf_size + MAX_ALIGNMENT]; |
| 153 | uint8_t dst_buf[buf_size + MAX_ALIGNMENT]; |
| 154 | std::iota(src_buf, src_buf + buf_size + MAX_ALIGNMENT, 1); |
| 155 | for (size_t i = 0; i < MAX_ALIGNMENT; ++i) { |
| 156 | for (size_t j = 0; j < MAX_ALIGNMENT; ++j) { |
| 157 | std::fill(dst_buf, dst_buf + buf_size + MAX_ALIGNMENT, 0); |
| 158 | bswap_fptr(src_buf + i, dst_buf + j); |
| 159 | |
| 160 | // Validate the swap results. |
| 161 | for (int k = 0; k < buf_size; ++k) { |
| 162 | EXPECT_EQ(dst_buf[k + j], 1 + i + buf_size - k - 1); |
| 163 | EXPECT_EQ(dst_buf[k + j], src_buf[i + buf_size - k - 1]); |
| 164 | } |
| 165 | } |
| 166 | } |
| 167 | } |
| 168 | |
| 169 | // Test the logic of ByteSwapSimd control flow using specified SIMD routine with an |
| 170 | // input/output buffer. |