// Copyright 2022 The Abseil Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "absl/crc/internal/non_temporal_memcpy.h" #include #include #include #include #include "gtest/gtest.h" namespace { struct TestParam { size_t copy_size; uint32_t src_offset; uint32_t dst_offset; }; class NonTemporalMemcpyTest : public testing::TestWithParam { protected: void SetUp() override { // Make buf_size multiple of 16 bytes. size_t buf_size = ((std::max(GetParam().src_offset, GetParam().dst_offset) + GetParam().copy_size) + 15) / 16 * 16; a_.resize(buf_size); b_.resize(buf_size); for (size_t i = 0; i < buf_size; i++) { a_[i] = static_cast(i % 256); b_[i] = ~a_[i]; } } std::vector a_, b_; }; TEST_P(NonTemporalMemcpyTest, SSEEquality) { uint8_t *src = a_.data() + GetParam().src_offset; uint8_t *dst = b_.data() + GetParam().dst_offset; absl::crc_internal::non_temporal_store_memcpy(dst, src, GetParam().copy_size); for (size_t i = 0; i < GetParam().copy_size; i++) { EXPECT_EQ(src[i], dst[i]); } } TEST_P(NonTemporalMemcpyTest, AVXEquality) { uint8_t* src = a_.data() + GetParam().src_offset; uint8_t* dst = b_.data() + GetParam().dst_offset; absl::crc_internal::non_temporal_store_memcpy_avx(dst, src, GetParam().copy_size); for (size_t i = 0; i < GetParam().copy_size; i++) { EXPECT_EQ(src[i], dst[i]); } } // 63B is smaller than one cacheline operation thus the non-temporal routine // will not be called. // 4352B is sufficient for testing 4092B data copy with room for offsets. constexpr TestParam params[] = { {63, 0, 0}, {58, 5, 5}, {61, 2, 0}, {61, 0, 2}, {58, 5, 2}, {4096, 0, 0}, {4096, 0, 1}, {4096, 0, 2}, {4096, 0, 3}, {4096, 0, 4}, {4096, 0, 5}, {4096, 0, 6}, {4096, 0, 7}, {4096, 0, 8}, {4096, 0, 9}, {4096, 0, 10}, {4096, 0, 11}, {4096, 0, 12}, {4096, 0, 13}, {4096, 0, 14}, {4096, 0, 15}, {4096, 7, 7}, {4096, 3, 0}, {4096, 1, 0}, {4096, 9, 3}, {4096, 9, 11}, {8192, 0, 0}, {8192, 5, 2}, {1024768, 7, 11}, {1, 0, 0}, {1, 0, 1}, {1, 1, 0}, {1, 1, 1}}; INSTANTIATE_TEST_SUITE_P(ParameterizedNonTemporalMemcpyTest, NonTemporalMemcpyTest, testing::ValuesIn(params)); } // namespace