Skip to content

Commit c82b3cd

Browse files
authored
Merge pull request #15 from cschreib/update
Update and bug fixes for alignment
2 parents 61b47d5 + 7a16d59 commit c82b3cd

8 files changed

+730
-323
lines changed

README.md

+40-38
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ Finally, because this library uses no global state (beyond the standard allocato
121121

122122
## Comparison spreadsheet
123123

124-
In this comparison spreadsheet, the raw pointer `T*` is assumed to never be owning, and used only to observe an existing object (which may or may not have been deleted). The stack and heap sizes were measured with gcc 9.3.0 and libstdc++.
124+
In this comparison spreadsheet, the raw pointer `T*` is assumed to never be owning, and used only to observe an existing object (which may or may not have been deleted). Unless otherwise specified, the stack and heap sizes were measured with gcc 9.4.0 and libstdc++-9.
125125

126126
Labels:
127127
- raw: `T*`
@@ -146,7 +146,7 @@ Labels:
146146
| Number of heap alloc. | 0 | 0 | 0 | 1 | 1/2(4) | 2 | 1 |
147147
| Size in bytes (64 bit) | | | | | | | |
148148
| - Stack (per instance) | 8 | 16 | 16 | 8 | 16 | 16 | 16 |
149-
| - Heap (shared) | 0 | 0 | 0 | 0 | 24 | 4 | 4 |
149+
| - Heap (shared) | 0 | 0 | 0 | 0 | 24(5) | 4 | 4(6) |
150150
| - Total | 8 | 16 | 16 | 8 | 40 | 20 | 20 |
151151
| Size in bytes (32 bit) | | | | | | | |
152152
| - Stack (per instance) | 4 | 8 | 8 | 4 | 8 | 8 | 8 |
@@ -159,13 +159,15 @@ Notes:
159159
- (2) Not if using `std::make_shared()`.
160160
- (3) Not defined by the C++ standard. In practice, libstdc++ stores its reference count on an `_Atomic_word`, which for a common 64bit linux platform is a 4 byte signed integer, hence the limit will be 2^31 - 1. Microsoft's STL uses `_Atomic_counter_t`, which for a 64bit Windows platform is 4 bytes unsigned integer, hence the limit will be 2^32 - 1.
161161
- (4) 2 by default, or 1 if using `std::make_shared()`.
162+
- (5) When using `std::make_shared()`, this can get as low as 16 bytes, or larger than 24 bytes, depending on the size and alignment requirements of the object type. This behavior is shared by libstdc++ and MS-STL.
163+
- (6) Can get larger than 4 depending on the alignment requirements of the object type.
162164

163165

164166
## Speed benchmarks
165167

166168
Labels are the same as in the comparison spreadsheet. The speed benchmarks were compiled with all optimizations turned on (except LTO). Speed is measured relative to `std::unique_ptr<T>` used as owner pointer, and `T*` used as observer pointer, which should be the fastest possible implementation (but obviously the one with least safety).
167169

168-
You can run the benchmarks yourself, they are located in `tests/speed_benchmark.cpp`. The benchmark executable runs tests for three object types: `int`, `float`, `std::string`, and `std::array<int,65'536>`, to simulate objects of various allocation cost. The timings below are the worst-case values measured across all object types, which should be most relevant to highlight the overhead from the pointer itself (and erases flukes from the benchmarking framework). In real life scenarios, the actual measured overhead will be substantially lower, as actual business logic is likely to dominate the time budget.
170+
You can run the benchmarks yourself, they are located in `tests/speed_benchmark.cpp`. The benchmark executable runs tests for three object types: `int`, `float`, `std::string`, and `std::array<int,65'536>`, to simulate objects of various allocation cost. The timings below are the median values measured across all object types, which should be most relevant to highlight the overhead from the pointer itself (and erases flukes from the benchmarking framework). In real life scenarios, the actual measured overhead will be substantially lower, as actual business logic is likely to dominate the time budget.
169171

170172
Detail of the benchmarks:
171173
- Create owner empty: default-construct an owner pointer (to nullptr).
@@ -177,46 +179,46 @@ Detail of the benchmarks:
177179
- Create observer copy: construct a new observer pointer from another observer pointer.
178180
- Dereference observer: get a reference to the underlying object from an observer pointer.
179181

180-
The benchmarks were last ran for v0.4.0.
182+
The benchmarks were last ran for oup v0.7.1.
181183

182-
*Compiler: gcc 9.3.0, std: libstdc++, OS: linux 5.1.0, CPU: Ryzen 5 2600:*
184+
*Compiler: gcc 9.4.0, std: libstdc++-9, OS: linux 5.15.0, CPU: Ryzen 5 2600:*
183185

184-
| Pointer | raw/unique | weak/shared | observer/obs_unique | observer/obs_sealed |
185-
|--------------------------|------------|-------------|---------------------|---------------------|
186-
| Create owner empty | 1 | 1.1 | 1.1 | 1.1 |
187-
| Create owner | 1 | 2.2 | 1.9 | N/A |
188-
| Create owner factory | 1 | 1.3 | 1.8 | 1.3 |
189-
| Dereference owner | 1 | 1 | 1 | 1 |
190-
| Create observer empty | 1 | 1.2 | 1.2 | 1.3 |
191-
| Create observer | 1 | 1.5 | 1.6 | 1.6 |
192-
| Create observer copy | 1 | 1.7 | 1.7 | 1.7 |
193-
| Dereference observer | 1 | 4.8 | 1.2 | 1.3 |
186+
| Pointer | raw/unique | weak/shared | observer/obs_unique | observer/obs_sealed |
187+
| --- | --- | --- | --- | --- |
188+
| Create owner empty | 1 | 1.1 | 1.1 | 1.2 |
189+
| Create owner | 1 | 2.1 | 1.7 | N/A |
190+
| Create owner factory | 1 | 1.3 | 1.7 | 1.1 |
191+
| Dereference owner | 1 | 1.0 | 1.0 | 1.1 |
192+
| Create observer empty | 1 | 1.1 | 1.2 | 1.2 |
193+
| Create observer | 1 | 1.6 | 1.6 | 1.6 |
194+
| Create observer copy | 1 | 1.7 | 1.6 | 1.6 |
195+
| Dereference observer | 1 | 3.5 | 1.0 | 1.0 |
194196

195197
*Compiler: MSVC 16.11.3, std: MS-STL, OS: Windows 10.0.19043, CPU: i7-7800x:*
196198

197-
| Pointer | raw/unique | weak/shared | observer/obs_unique | observer/obs_sealed |
198-
|--------------------------|------------|-------------|---------------------|---------------------|
199-
| Create owner empty | 1 | 1.1 | 1.1 | 1.1 |
200-
| Create owner | 1 | 2.2 | 2.0 | N/A |
201-
| Create owner factory | 1 | 1.3 | 2.0 | 1.4 |
202-
| Dereference owner | 1 | 0.8 | 1.8 | 1.5 |
203-
| Create observer empty | 1 | 1.1 | 1.2 | 1.2 |
204-
| Create observer | 1 | 5.6 | 1.5 | 1.3 |
205-
| Create observer copy | 1 | 6.2 | 1.4 | 1.3 |
206-
| Dereference observer | 1 | 11 | 1.5 | 1.1 |
207-
208-
*Compiler: Emscripten 2.0.16, std: libc++, OS: Node.js 14.15.5 + linux kernel 5.1.0, CPU: Ryzen 5 2600:*
209-
210-
| Pointer | raw/unique | weak/shared | observer/obs_unique | observer/obs_sealed |
211-
|--------------------------|------------|-------------|---------------------|---------------------|
212-
| Create owner empty | 1 | 20 | 1.2 | 1 |
213-
| Create owner | 1 | 1.6 | 1.6 | N/A |
214-
| Create owner factory | 1 | 1.1 | 1.6 | 1 |
215-
| Dereference owner | 1 | 1 | 1 | 1 |
216-
| Create observer empty | 1 | 35 | 1.8 | 1.7 |
217-
| Create observer | 1 | 36 | 2.4 | 2.5 |
218-
| Create observer copy | 1 | 41 | 2.3 | 2.3 |
219-
| Dereference observer | 1 | 114 | 1 | 1 |
199+
| Pointer | raw/unique | weak/shared | observer/obs_unique | observer/obs_sealed |
200+
| --- | --- | --- | --- | --- |
201+
| Create owner empty | 1 | 1.4 | 1.8 | 1.5 |
202+
| Create owner | 1 | 2.2 | 2.9 | N/A |
203+
| Create owner factory | 1 | 1.2 | 2.2 | 0.9 |
204+
| Dereference owner | 1 | 0.7 | 1.3 | 1.0 |
205+
| Create observer empty | 1 | 1.6 | 1.0 | 0.8 |
206+
| Create observer | 1 | 5.3 | 1.6 | 1.6 |
207+
| Create observer copy | 1 | 5.3 | 1.4 | 1.5 |
208+
| Dereference observer | 1 | 9.4 | 1.4 | 0.8 |
209+
210+
*Compiler: Emscripten 2.0.34, std: libc++, OS: Node.js 14.15.5 + linux kernel 5.1.0, CPU: Ryzen 5 2600:*
211+
212+
| Pointer | raw/unique | weak/shared | observer/obs_unique | observer/obs_sealed |
213+
| --- | --- | --- | --- | --- |
214+
| Create owner empty | 1 | 6.9 | 1.1 | 1.0 |
215+
| Create owner | 1 | 1.8 | 1.6 | N/A |
216+
| Create owner factory | 1 | 1.2 | 1.7 | 1.0 |
217+
| Dereference owner | 1 | 1.0 | 1.0 | 1.0 |
218+
| Create observer empty | 1 | 11.4 | 1.6 | 1.6 |
219+
| Create observer | 1 | 14.8 | 2.3 | 2.3 |
220+
| Create observer copy | 1 | 14.9 | 2.3 | 2.5 |
221+
| Dereference observer | 1 | 38.7 | 1.0 | 1.0 |
220222

221223

222224
## Alternative implementation

0 commit comments

Comments
 (0)