crc_memcpy_fallback.cc (2888B)
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 <cstring> 16 #include <memory> 17 18 #include "absl/base/config.h" 19 #include "absl/crc/crc32c.h" 20 #include "absl/crc/internal/crc_memcpy.h" 21 #include "absl/strings/string_view.h" 22 23 namespace absl { 24 ABSL_NAMESPACE_BEGIN 25 namespace crc_internal { 26 27 absl::crc32c_t FallbackCrcMemcpyEngine::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 absl::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. CRC 38 // then copy was found to be slightly more efficient in our test cases. 39 std::size_t offset = 0; 40 for (; offset + kBlockSize < length; offset += kBlockSize) { 41 crc = absl::ExtendCrc32c(crc, 42 absl::string_view(src_bytes + offset, kBlockSize)); 43 memcpy(dst_bytes + offset, src_bytes + offset, 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 = absl::ExtendCrc32c( 50 crc, absl::string_view(src_bytes + offset, final_copy_size)); 51 memcpy(dst_bytes + offset, src_bytes + offset, final_copy_size); 52 } 53 54 return crc; 55 } 56 57 // Compile the following only if we don't have 58 #if !defined(ABSL_INTERNAL_HAVE_X86_64_ACCELERATED_CRC_MEMCPY_ENGINE) && \ 59 !defined(ABSL_INTERNAL_HAVE_ARM_ACCELERATED_CRC_MEMCPY_ENGINE) 60 61 CrcMemcpy::ArchSpecificEngines CrcMemcpy::GetArchSpecificEngines() { 62 CrcMemcpy::ArchSpecificEngines engines; 63 engines.temporal = new FallbackCrcMemcpyEngine(); 64 engines.non_temporal = new FallbackCrcMemcpyEngine(); 65 return engines; 66 } 67 68 std::unique_ptr<CrcMemcpyEngine> CrcMemcpy::GetTestEngine(int /*vector*/, 69 int /*integer*/) { 70 return std::make_unique<FallbackCrcMemcpyEngine>(); 71 } 72 73 #endif // !ABSL_INTERNAL_HAVE_X86_64_ACCELERATED_CRC_MEMCPY_ENGINE && 74 // !ABSL_INTERNAL_HAVE_ARM_ACCELERATED_CRC_MEMCPY_ENGINE 75 76 } // namespace crc_internal 77 ABSL_NAMESPACE_END 78 } // namespace absl