Google OR-Tools v9.11
a fast and portable software suite for combinatorial optimization
Loading...
Searching...
No Matches
aligned_memory.h
Go to the documentation of this file.
1// Copyright 2010-2024 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// Provides functions and data structures that make it easier to work with
15// aligned memory:
16//
17// - AlignedAllocator<T, n>, an extension of std::allocator<T> that also takes
18// an explicit memory alignment parameter. The memory blocks returned by the
19// allocator are aligned to this number of bytes, i.e. the address of the
20// beginning of the block will be N * alignment_bytes for some N.
21// - AlignedVector<>, a specialization of std::vector<> that uses the aligned
22// allocator to create blocks with explicit allocations.
23//
24// - AlignUp and AlignDown are functions that align a pointer to the given
25// number of bytes.
26
27#ifndef OR_TOOLS_UTIL_ALIGNED_MEMORY_H_
28#define OR_TOOLS_UTIL_ALIGNED_MEMORY_H_
29
30#include <cstddef>
31#include <cstdint>
32#include <vector>
33
35
36namespace operations_research {
37
38// Functions for working with pointers and rounding them up and down to a given
39// alignment.
40
41// Returns the nearest greater or equal address that is a multiple of
42// alignment_bytes. When ptr is already aligned to alignment_bytes, returns it
43// unchanged.
44template <size_t alignment_bytes, typename Value>
45inline Value* AlignUp(Value* ptr) {
46 const std::uintptr_t int_ptr = reinterpret_cast<std::intptr_t>(ptr);
47 const std::uintptr_t misalignment = int_ptr % alignment_bytes;
48 if (misalignment == 0) return ptr;
49 return reinterpret_cast<Value*>(int_ptr - misalignment + alignment_bytes);
50}
51
52// Returns the nearest smaller or equal address that is a multiple of
53// alignment_bytes. When ptr is already aligned to alignment_bytes, returns it
54// unchanged
55template <size_t alignment_bytes, typename Value>
56inline Value* AlignDown(Value* ptr) {
57 const std::intptr_t int_ptr = reinterpret_cast<std::intptr_t>(ptr);
58 const std::intptr_t misalignment = int_ptr % alignment_bytes;
59 return reinterpret_cast<Value*>(int_ptr - misalignment);
60}
61
62// Returns true when `ptr` is aligned to `alignment_bytes` bytes.
63template <size_t alignment_bytes, typename Value>
64inline bool IsAligned(Value* ptr) {
65 return reinterpret_cast<std::uintptr_t>(ptr) % alignment_bytes == 0;
66}
67
68// Support for aligned containers in STL.
69
70// An allocator that always aligns its memory to `alignment_bytes`.
71template <typename T, size_t alignment_bytes>
74
75// A version of std::vector<T> whose data() pointer is always aligned to
76// `alignment_bytes`.
77template <typename T, size_t alignment_bytes>
78using AlignedVector = std::vector<T, AlignedAllocator<T, alignment_bytes>>;
79
80// Intentionally misaligned containers for testing correctness and performance
81// of code that may depend on a certain alignment.
82namespace use_only_in_tests {
83
84// A version of AlignedAllocator for testing purposes that adds intentional
85// misalignment. The returned address has the form
86// alignment_bytes * N + misalignment_bytes.
87template <typename T, size_t alignment_bytes, size_t misalignment_bytes>
90
91// A specialization of std::vector<> that uses MisalignedAllocator with the
92// given parameters.
93template <typename T, size_t alignment_bytes, size_t misalignment_bytes>
95 std::vector<T, MisalignedAllocator<T, alignment_bytes, misalignment_bytes>>;
96
97} // namespace use_only_in_tests
98
99} // namespace operations_research
100
101#endif // OR_TOOLS_UTIL_ALIGNED_MEMORY_H_
std::vector< T, MisalignedAllocator< T, alignment_bytes, misalignment_bytes > > MisalignedVector
In SWIG mode, we don't want anything besides these top-level includes.
bool IsAligned(Value *ptr)
Returns true when ptr is aligned to alignment_bytes bytes.
std::vector< T, AlignedAllocator< T, alignment_bytes > > AlignedVector
Value * AlignUp(Value *ptr)
Value * AlignDown(Value *ptr)