1 /*
2  * Copyright (C) 2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "alignment_selector.h"
9 
10 #include "shared/source/helpers/aligned_memory.h"
11 #include "shared/source/helpers/debug_helpers.h"
12 
13 #include <algorithm>
14 #include <cstring>
15 
16 namespace NEO {
17 
operator ==(const AlignmentSelector::CandidateAlignment & lhs,const AlignmentSelector::CandidateAlignment & rhs)18 bool operator==(const AlignmentSelector::CandidateAlignment &lhs, const AlignmentSelector::CandidateAlignment &rhs) {
19     return std::tie(lhs.alignment, lhs.applyForSmallerSize, lhs.heap, lhs.maxMemoryWastage) ==
20            std::tie(rhs.alignment, rhs.applyForSmallerSize, rhs.heap, rhs.maxMemoryWastage);
21 }
22 
addCandidateAlignment(size_t alignment,bool applyForSmallerSize,float maxMemoryWastage)23 void AlignmentSelector::addCandidateAlignment(size_t alignment, bool applyForSmallerSize, float maxMemoryWastage) {
24     this->addCandidateAlignment(alignment, applyForSmallerSize, maxMemoryWastage, HeapIndex::TOTAL_HEAPS);
25 }
26 
addCandidateAlignment(size_t alignment,bool applyForSmallerSize,float maxMemoryWastage,HeapIndex heap)27 void AlignmentSelector::addCandidateAlignment(size_t alignment, bool applyForSmallerSize, float maxMemoryWastage, HeapIndex heap) {
28     UNRECOVERABLE_IF(alignment == 0);
29     UNRECOVERABLE_IF((alignment & (alignment - 1)) != 0); // must be power of 2
30 
31     CandidateAlignment candidateAlignment{};
32     candidateAlignment.alignment = alignment;
33     candidateAlignment.applyForSmallerSize = applyForSmallerSize;
34     candidateAlignment.maxMemoryWastage = maxMemoryWastage;
35     candidateAlignment.heap = heap;
36     this->candidateAlignments.push_back(std::move(candidateAlignment));
37 
38     const auto comparator = [](const CandidateAlignment &left, const CandidateAlignment &right) {
39         return left.alignment > right.alignment;
40     };
41     std::sort(this->candidateAlignments.begin(), this->candidateAlignments.end(), comparator);
42 }
43 
selectAlignment(size_t size) const44 AlignmentSelector::CandidateAlignment AlignmentSelector::selectAlignment(size_t size) const {
45     for (const CandidateAlignment &candidateAlignment : this->candidateAlignments) {
46         if (!candidateAlignment.applyForSmallerSize && size < candidateAlignment.alignment) {
47             continue;
48         }
49 
50         const size_t alignedSize = alignUp(size, candidateAlignment.alignment);
51         const size_t wastedMemory = alignedSize - size;
52         const size_t maxWastedMemory = static_cast<size_t>(alignedSize * candidateAlignment.maxMemoryWastage);
53         if (wastedMemory > maxWastedMemory) {
54             continue;
55         }
56 
57         return candidateAlignment;
58     }
59     UNRECOVERABLE_IF(true);
60 }
61 } // namespace NEO
62