1 //===-- Benchmark memory specific tools -----------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "LibcMemoryBenchmark.h" 10 #include "llvm/ADT/SmallVector.h" 11 #include "llvm/Support/ErrorHandling.h" 12 #include "llvm/Support/MathExtras.h" 13 #include <algorithm> 14 15 namespace llvm { 16 namespace libc_benchmarks { 17 18 // Returns a distribution that samples the buffer to satisfy the required 19 // alignment. 20 // When alignment is set, the distribution is scaled down by `Factor` and scaled 21 // up again by the same amount during sampling. 22 static std::uniform_int_distribution<uint32_t> 23 getOffsetDistribution(size_t BufferSize, size_t MaxSizeValue, 24 MaybeAlign AccessAlignment) { 25 if (AccessAlignment && *AccessAlignment > AlignedBuffer::Alignment) 26 report_fatal_error( 27 "AccessAlignment must be less or equal to AlignedBuffer::Alignment"); 28 if (!AccessAlignment) 29 return std::uniform_int_distribution<uint32_t>(0, 0); // Always 0. 30 // If we test up to Size bytes, the returned offset must stay under 31 // BuffersSize - Size. 32 int64_t MaxOffset = BufferSize; 33 MaxOffset -= MaxSizeValue; 34 MaxOffset -= 1; 35 if (MaxOffset < 0) 36 report_fatal_error( 37 "BufferSize too small to exercise specified Size configuration"); 38 MaxOffset /= AccessAlignment->value(); 39 return std::uniform_int_distribution<uint32_t>(0, MaxOffset); 40 } 41 42 OffsetDistribution::OffsetDistribution(size_t BufferSize, size_t MaxSizeValue, 43 MaybeAlign AccessAlignment) 44 : Distribution( 45 getOffsetDistribution(BufferSize, MaxSizeValue, AccessAlignment)), 46 Factor(AccessAlignment.valueOrOne().value()) {} 47 48 // Precomputes offset where to insert mismatches between the two buffers. 49 MismatchOffsetDistribution::MismatchOffsetDistribution(size_t BufferSize, 50 size_t MaxSizeValue, 51 size_t MismatchAt) 52 : MismatchAt(MismatchAt) { 53 if (MismatchAt <= 1) 54 return; 55 for (size_t I = MaxSizeValue + 1; I < BufferSize; I += MaxSizeValue) 56 MismatchIndices.push_back(I); 57 if (MismatchIndices.empty()) 58 report_fatal_error("Unable to generate mismatch"); 59 MismatchIndexSelector = 60 std::uniform_int_distribution<size_t>(0, MismatchIndices.size() - 1); 61 } 62 63 } // namespace libc_benchmarks 64 } // namespace llvm 65