crc_non_temporal_memcpy.cc (3365B)
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 <cstddef> 16 17 #include "absl/base/config.h" 18 #include "absl/crc/crc32c.h" 19 #include "absl/crc/internal/crc_memcpy.h" 20 #include "absl/crc/internal/non_temporal_memcpy.h" 21 #include "absl/strings/string_view.h" 22 23 namespace absl { 24 ABSL_NAMESPACE_BEGIN 25 namespace crc_internal { 26 27 crc32c_t CrcNonTemporalMemcpyEngine::Compute(void* __restrict dst, 28 const void* __restrict src, 29 std::size_t length, 30 crc32c_t initial_crc) const { 31 constexpr size_t kBlockSize = 8192; 32 crc32c_t crc = initial_crc; 33 34 const char* src_bytes = reinterpret_cast<const char*>(src); 35 char* dst_bytes = reinterpret_cast<char*>(dst); 36 37 // Copy + CRC loop - run 8k chunks until we are out of full chunks. 38 std::size_t offset = 0; 39 for (; offset + kBlockSize < length; offset += kBlockSize) { 40 crc = absl::ExtendCrc32c(crc, 41 absl::string_view(src_bytes + offset, kBlockSize)); 42 non_temporal_store_memcpy(dst_bytes + offset, src_bytes + offset, 43 kBlockSize); 44 } 45 46 // Save some work if length is 0. 47 if (offset < length) { 48 std::size_t final_copy_size = length - offset; 49 crc = ExtendCrc32c(crc, 50 absl::string_view(src_bytes + offset, final_copy_size)); 51 52 non_temporal_store_memcpy(dst_bytes + offset, src_bytes + offset, 53 final_copy_size); 54 } 55 56 return crc; 57 } 58 59 crc32c_t CrcNonTemporalMemcpyAVXEngine::Compute(void* __restrict dst, 60 const void* __restrict src, 61 std::size_t length, 62 crc32c_t initial_crc) const { 63 constexpr size_t kBlockSize = 8192; 64 crc32c_t crc = initial_crc; 65 66 const char* src_bytes = reinterpret_cast<const char*>(src); 67 char* dst_bytes = reinterpret_cast<char*>(dst); 68 69 // Copy + CRC loop - run 8k chunks until we are out of full chunks. 70 std::size_t offset = 0; 71 for (; offset + kBlockSize < length; offset += kBlockSize) { 72 crc = ExtendCrc32c(crc, absl::string_view(src_bytes + offset, kBlockSize)); 73 74 non_temporal_store_memcpy_avx(dst_bytes + offset, src_bytes + offset, 75 kBlockSize); 76 } 77 78 // Save some work if length is 0. 79 if (offset < length) { 80 std::size_t final_copy_size = length - offset; 81 crc = ExtendCrc32c(crc, 82 absl::string_view(src_bytes + offset, final_copy_size)); 83 84 non_temporal_store_memcpy_avx(dst_bytes + offset, src_bytes + offset, 85 final_copy_size); 86 } 87 88 return crc; 89 } 90 91 } // namespace crc_internal 92 ABSL_NAMESPACE_END 93 } // namespace absl