proxygen
Align.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <cstddef>
20 
21 #include <folly/Portability.h>
22 
23 namespace folly {
24 
25 namespace detail {
26 
27 // Implemented this way because of a bug in Clang for ARMv7, which gives the
28 // wrong result for `alignof` a `union` with a field of each scalar type.
29 constexpr size_t max_align_(std::size_t a) {
30  return a;
31 }
32 template <typename... Es>
33 constexpr std::size_t max_align_(std::size_t a, std::size_t e, Es... es) {
34  return !(a < e) ? a : max_align_(e, es...);
35 }
36 template <typename... Ts>
37 struct max_align_t_ {
38  static constexpr std::size_t value = max_align_(0u, alignof(Ts)...);
39 };
41  long double,
42  double,
43  float,
44  long long int,
45  long int,
46  int,
47  short int,
48  bool,
49  char,
50  char16_t,
51  char32_t,
52  wchar_t,
53  void*,
54  std::max_align_t>;
55 
56 } // namespace detail
57 
58 // max_align_v is the alignment of max_align_t.
59 //
60 // max_align_t is a type which is aligned at least as strictly as the
61 // most-aligned basic type (see the specification of std::max_align_t). This
62 // implementation exists because 32-bit iOS platforms have a broken
63 // std::max_align_t (see below).
64 //
65 // You should refer to this as `::folly::max_align_t` in portable code, even if
66 // you have `using namespace folly;` because C11 defines a global namespace
67 // `max_align_t` type.
68 //
69 // To be certain, we consider every non-void fundamental type specified by the
70 // standard. On most platforms `long double` would be enough, but iOS 32-bit
71 // has an 8-byte aligned `double` and `long long int` and a 4-byte aligned
72 // `long double`.
73 //
74 // So far we've covered locals and other non-allocated storage, but we also need
75 // confidence that allocated storage from `malloc`, `new`, etc will also be
76 // suitable for objects with this alignment requirement.
77 //
78 // Apple document that their implementation of malloc will issue 16-byte
79 // granularity chunks for small allocations (large allocations are page-size
80 // granularity and page-aligned). We think that allocated storage will be
81 // suitable for these objects based on the following assumptions:
82 //
83 // 1. 16-byte granularity also means 16-byte aligned.
84 // 2. `new` and other allocators follow the `malloc` rules.
85 //
86 // We also have some anecdotal evidence: we don't see lots of misaligned-storage
87 // crashes on 32-bit iOS apps that use `double`.
88 //
89 // Apple's allocation reference: http://bit.ly/malloc-small
90 constexpr std::size_t max_align_v = detail::max_align_v_::value;
91 struct alignas(max_align_v) max_align_t {};
92 
93 // Memory locations within the same cache line are subject to destructive
94 // interference, also known as false sharing, which is when concurrent
95 // accesses to these different memory locations from different cores, where at
96 // least one of the concurrent accesses is or involves a store operation,
97 // induce contention and harm performance.
98 //
99 // Microbenchmarks indicate that pairs of cache lines also see destructive
100 // interference under heavy use of atomic operations, as observed for atomic
101 // increment on Sandy Bridge.
102 //
103 // We assume a cache line size of 64, so we use a cache line pair size of 128
104 // to avoid destructive interference.
105 //
106 // mimic: std::hardware_destructive_interference_size, C++17
108  kIsArchArm ? 64 : 128;
109 static_assert(hardware_destructive_interference_size >= max_align_v, "math?");
110 
111 // Memory locations within the same cache line are subject to constructive
112 // interference, also known as true sharing, which is when accesses to some
113 // memory locations induce all memory locations within the same cache line to
114 // be cached, benefiting subsequent accesses to different memory locations
115 // within the same cache line and heping performance.
116 //
117 // mimic: std::hardware_constructive_interference_size, C++17
118 constexpr std::size_t hardware_constructive_interference_size = 64;
119 static_assert(hardware_constructive_interference_size >= max_align_v, "math?");
120 
121 } // namespace folly
static constexpr std::size_t value
Definition: Align.h:38
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
constexpr size_t max_align_(std::size_t a)
Definition: Align.h:29
constexpr std::size_t max_align_v
Definition: Align.h:90
constexpr std::size_t hardware_destructive_interference_size
Definition: Align.h:107
char a
constexpr std::size_t hardware_constructive_interference_size
Definition: Align.h:118
constexpr bool kIsArchArm
Definition: Portability.h:101