non_temporal_memcpy_test.cc (3032B)
1 // Copyright 2022 The Abseil Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "absl/crc/internal/non_temporal_memcpy.h" 16 17 #include <algorithm> 18 #include <cstdint> 19 #include <iostream> 20 #include <vector> 21 22 #include "gtest/gtest.h" 23 24 namespace { 25 26 struct TestParam { 27 size_t copy_size; 28 uint32_t src_offset; 29 uint32_t dst_offset; 30 }; 31 32 class NonTemporalMemcpyTest : public testing::TestWithParam<TestParam> { 33 protected: 34 void SetUp() override { 35 // Make buf_size multiple of 16 bytes. 36 size_t buf_size = ((std::max(GetParam().src_offset, GetParam().dst_offset) + 37 GetParam().copy_size) + 38 15) / 39 16 * 16; 40 a_.resize(buf_size); 41 b_.resize(buf_size); 42 for (size_t i = 0; i < buf_size; i++) { 43 a_[i] = static_cast<uint8_t>(i % 256); 44 b_[i] = ~a_[i]; 45 } 46 } 47 48 std::vector<uint8_t> a_, b_; 49 }; 50 51 TEST_P(NonTemporalMemcpyTest, SSEEquality) { 52 uint8_t *src = a_.data() + GetParam().src_offset; 53 uint8_t *dst = b_.data() + GetParam().dst_offset; 54 absl::crc_internal::non_temporal_store_memcpy(dst, src, GetParam().copy_size); 55 for (size_t i = 0; i < GetParam().copy_size; i++) { 56 EXPECT_EQ(src[i], dst[i]); 57 } 58 } 59 60 #ifdef __AVX__ 61 TEST_P(NonTemporalMemcpyTest, AVXEquality) { 62 uint8_t* src = a_.data() + GetParam().src_offset; 63 uint8_t* dst = b_.data() + GetParam().dst_offset; 64 65 absl::crc_internal::non_temporal_store_memcpy_avx(dst, src, 66 GetParam().copy_size); 67 for (size_t i = 0; i < GetParam().copy_size; i++) { 68 EXPECT_EQ(src[i], dst[i]); 69 } 70 } 71 #endif 72 73 // 63B is smaller than one cacheline operation thus the non-temporal routine 74 // will not be called. 75 // 4352B is sufficient for testing 4092B data copy with room for offsets. 76 constexpr TestParam params[] = { 77 {63, 0, 0}, {58, 5, 5}, {61, 2, 0}, {61, 0, 2}, 78 {58, 5, 2}, {4096, 0, 0}, {4096, 0, 1}, {4096, 0, 2}, 79 {4096, 0, 3}, {4096, 0, 4}, {4096, 0, 5}, {4096, 0, 6}, 80 {4096, 0, 7}, {4096, 0, 8}, {4096, 0, 9}, {4096, 0, 10}, 81 {4096, 0, 11}, {4096, 0, 12}, {4096, 0, 13}, {4096, 0, 14}, 82 {4096, 0, 15}, {4096, 7, 7}, {4096, 3, 0}, {4096, 1, 0}, 83 {4096, 9, 3}, {4096, 9, 11}, {8192, 0, 0}, {8192, 5, 2}, 84 {1024768, 7, 11}, {1, 0, 0}, {1, 0, 1}, {1, 1, 0}, 85 {1, 1, 1}}; 86 87 INSTANTIATE_TEST_SUITE_P(ParameterizedNonTemporalMemcpyTest, 88 NonTemporalMemcpyTest, testing::ValuesIn(params)); 89 90 } // namespace