Library: investigate alignment issues
The solution implemented thus far turns out to be not sufficient for ''over-aligned-data'', as the raw-allocator can not perform the ''magic work'' because we're exposing only `std::byte` data.
This commit is contained in:
parent
055df59dde
commit
dc6c8e0858
4 changed files with 149 additions and 13 deletions
|
|
@ -73,7 +73,7 @@ namespace lib {
|
|||
|
||||
namespace {// Storage implementation details
|
||||
|
||||
template<class I>
|
||||
template<class I, class E =I, size_t space = sizeof(I)>
|
||||
struct ArrayBucket
|
||||
{
|
||||
ArrayBucket (size_t bytes, size_t elmSize = sizeof(I))
|
||||
|
|
@ -91,9 +91,8 @@ namespace lib {
|
|||
Deleter deleter;
|
||||
|
||||
/** mark start of the storage area */
|
||||
alignas(I)
|
||||
alignas(void*)
|
||||
std::byte storage[sizeof(I)];
|
||||
alignas(E)
|
||||
std::byte storage[space];
|
||||
|
||||
|
||||
static size_t
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/test/tracking-dummy.hpp"
|
||||
#include "lib/test/tracking-allocator.hpp"
|
||||
#include "lib/test/test-coll.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/test/diagnostic-output.hpp"////////////////TODO
|
||||
|
|
@ -508,6 +509,26 @@ namespace test{
|
|||
alignas(32)
|
||||
char charm = 'u';
|
||||
};
|
||||
SHOW_EXPR(sizeof(Ali))
|
||||
SHOW_EXPR(alignof(Ali))
|
||||
SHOW_EXPR(sizeof(ArrayBucket<Ali>))
|
||||
SHOW_EXPR(alignof(ArrayBucket<Ali>))
|
||||
SHOW_EXPR(sizeof(ArrayBucket<Ali, Ali, 10>))
|
||||
SHOW_EXPR(alignof(ArrayBucket<Ali, Ali, 10>))
|
||||
SHOW_EXPR(sizeof(ArrayBucket<char, Ali, 10>))
|
||||
SHOW_EXPR(alignof(ArrayBucket<char, Ali, 10>))
|
||||
|
||||
std::allocator<ArrayBucket<Ali>> aliAllo;
|
||||
std::allocator<std::byte> byteAllo;
|
||||
|
||||
ArrayBucket<Ali> * locAli = aliAllo.allocate(1);
|
||||
std::byte* locByte = byteAllo.allocate(96);
|
||||
SHOW_EXPR(loc(locAli))
|
||||
SHOW_EXPR(loc(locAli) % alignof(Ali))
|
||||
SHOW_EXPR(loc(locByte))
|
||||
SHOW_EXPR(loc(locByte) % alignof(Ali))
|
||||
aliAllo.destroy(locAli);
|
||||
byteAllo.destroy(locByte);
|
||||
|
||||
auto elms = makeSeveral<Ali>().fillElm(5).build();
|
||||
CHECK (5 == elms.size());
|
||||
|
|
@ -551,11 +572,18 @@ namespace test{
|
|||
|
||||
|
||||
/** @test TODO demonstrate integration with a custom allocator
|
||||
* @todo WIP 6/24 🔁 define ⟶ implement
|
||||
* @todo WIP 6/24 🔁 define ⟶ 🔁 implement
|
||||
*/
|
||||
void
|
||||
check_CustomAllocator()
|
||||
{
|
||||
{
|
||||
auto builder = makeSeveral<Dummy>()
|
||||
.withAllocator<test::TrackAlloc>();
|
||||
SHOW_TYPE(decltype(builder))
|
||||
SHOW_EXPR(builder.size())
|
||||
SHOW_EXPR(builder.capacity())
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ namespace test{
|
|||
void
|
||||
demonstrate_checkAllocator()
|
||||
{
|
||||
// setup a common lock for the tracking objects and -allocator
|
||||
// setup a common event-log for the tracking objects and -allocator
|
||||
auto& log = TrackingAllocator::log;
|
||||
Tracker::log.clear("Tracking-Allocator-Test");
|
||||
Tracker::log.joinInto(log);
|
||||
|
|
|
|||
|
|
@ -81799,7 +81799,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#4e3b7f" CREATED="1718034857705" FOLDED="true" ID="ID_725324060" MODIFIED="1718294109135" TEXT="Alignment beachten">
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#4e3b7f" CREATED="1718034857705" ID="ID_725324060" MODIFIED="1718586182698" TEXT="Alignment beachten">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1718035817292" ID="ID_908227037" MODIFIED="1718035826853" TEXT="Verwendungen von sizeof(TY)">
|
||||
<icon BUILTIN="idea"/>
|
||||
|
|
@ -81884,8 +81884,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1718066378097" ID="ID_1766969093" MODIFIED="1718067200842" TEXT="Anpassungen am Code (»grob korrekt«)">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1718066378097" ID="ID_1766969093" MODIFIED="1718588133769" TEXT="Anpassungen am Code">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#338800" CREATED="1718066394480" ID="ID_326301567" MODIFIED="1718067158583" TEXT="Puffer-Alignment ⟶ void*">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
|
|
@ -81895,6 +81895,99 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
<node COLOR="#338800" CREATED="1718067163803" ID="ID_1053644006" MODIFIED="1718067198266" TEXT=""sizeof(TY)" ⟼ reqSiz<TY>()">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718586230120" ID="ID_1182714506" MODIFIED="1718586304461" TEXT="Puffer für Alignment-Anpassung vorhalten">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1718586710311" ID="ID_180065995" MODIFIED="1718586719200" TEXT="Overhead erkennen"/>
|
||||
<node BACKGROUND_COLOR="#f8f1cb" COLOR="#a50125" CREATED="1718586719814" ID="ID_492092838" MODIFIED="1718586735029" TEXT="Folgeproblem: Größe der Gesamt-Allokation für clean-up">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1718586736516" ID="ID_1186615431" MODIFIED="1718586891007" TEXT="bisher ließ sich diese leicht errechnen">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
auf Basis der buffSiz, d.h. der Größe des reinen Nutzdatenpuffers; auf diese konnte man noch den statisch ermittelbaren Overhead aufschlagen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1718586893951" ID="ID_449167461" MODIFIED="1718587158319" TEXT="aber wir haben das Problem, daß nun irgendein Offset oben drauf kommt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Der Allocator macht nur eine raw-storage-Allocation, da is nix mit Alignment. Insofern kann der Beginn des gelieferten Speicherbereichs auch „daneben liegen“ — so daß wir einen Korrektur-Offset brauchen. Und der läßt sich nicht systematisch erschließen
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#f0d5c5" COLOR="#990033" CREATED="1718588145261" ID="ID_922709678" MODIFIED="1718634806800" TEXT="also »back to square one« — wir müssen den Offset speichern...">
|
||||
<icon BUILTIN="help"/>
|
||||
<node CREATED="1718634808255" ID="ID_1712579568" MODIFIED="1718634813576" TEXT="nein müssen wir nicht">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node CREATED="1718634816323" ID="ID_1531636233" MODIFIED="1718634923456" TEXT="dem Allokator kann der volle Typ gegeben werden">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Der Aufruf des Allokators erfolgt aus dem Builder, und <i>an der Stelle ist ohne Weiteres der volle Typ konstelliert</i>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1718634854895" ID="ID_872082102" MODIFIED="1718634878162" TEXT="nur das Front-End ist auf den vereinfachten Typ festgelegt"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1718586250781" ID="ID_984021528" MODIFIED="1718586384880" TEXT="das ArrayBucket korrekt im Puffer platzieren">
|
||||
<linktarget COLOR="#d4095b" DESTINATION="ID_984021528" ENDARROW="Default" ENDINCLINATION="-356;23;" ID="Arrow_ID_628657346" SOURCE="ID_1877181499" STARTARROW="None" STARTINCLINATION="552;-65;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1718587577355" ID="ID_305228810" MODIFIED="1718587885224" TEXT="mit dem Allocator-Framework passiert das nicht korrekt">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
<node CREATED="1718587596641" ID="ID_810422938" MODIFIED="1718587728564" TEXT="es gäbe eine spezielle Variante von operator new, die ein Alignment nimmt">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...to allocate storage required for a single object whose alignment requirement exceeds __STDCPP_DEFAULT_NEW_ALIGNMENT__
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1718587730599" ID="ID_1733586133" MODIFIED="1718587745801" TEXT="die gilt aber nur für Heap-Allocationen, nicht für placement-New"/>
|
||||
<node CREATED="1718587887730" ID="ID_1109606143" MODIFIED="1718587909154" TEXT="normalerweise würde man (deshalb!) schon die Raw-Allocation getypt machen">
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
<node CREATED="1718587914837" ID="ID_1255089684" MODIFIED="1718587997588" TEXT="also „beißt“ uns jetzt wieder genau das Problem mit der dynamischen Puffergröße">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
...weshalb ich ja keinen wirklich passenden statischen Typ für ArrayBucket angeben kann, weil die Puffergröße erst zur Laufzeit bekannt wird.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1718588000183" ID="ID_1990467161" MODIFIED="1718588028739" TEXT="⟹ selber machen (aus Gründen der Klarheit)">
|
||||
<node CREATED="1718588032517" ID="ID_1492285935" MODIFIED="1718588046931" TEXT="das ist so ein tückisches Problem, das formuliert man besser explizit"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1718067214231" ID="ID_1276439764" LINK="#ID_1830672111" MODIFIED="1718293971538" TEXT="testen"/>
|
||||
</node>
|
||||
</node>
|
||||
|
|
@ -83725,8 +83818,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
Der Zweck der TrackingFactory ist es, das saubere Verhalten eines Custom-Allocators zu belegen. In Grenzfällen könnte das zwar auch Concurrency involvieren — jedoch ist es aus heutigem Verständnis generell <b>nicht mehr üblich, Allokationen in der »heißen Zone« zu machen</b>. Typischerweise verwendet man genau dafür einen Builder oder einen Pool und teilt die Ressourcen schon im Vorhinen den Threads zu.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="stop-sign"/>
|
||||
</node>
|
||||
<node CREATED="1718571040189" ID="ID_1360340759" MODIFIED="1718571734976">
|
||||
|
|
@ -84222,6 +84314,24 @@ Date:   Thu Apr 20 18:53:17 2023 +0200<br/>
|
|||
</body>
|
||||
</html></richcontent>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#e0ceaa" COLOR="#690f14" CREATED="1718586280657" ID="ID_1877181499" MODIFIED="1718586384880" TEXT="leider genügt das noch nicht...">
|
||||
<arrowlink COLOR="#d4095b" DESTINATION="ID_984021528" ENDARROW="Default" ENDINCLINATION="-356;23;" ID="Arrow_ID_628657346" STARTARROW="None" STARTINCLINATION="552;-65;"/>
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node BACKGROUND_COLOR="#fafe99" COLOR="#fa002a" CREATED="1718586388686" ID="ID_1438922097" MODIFIED="1718586483948" TEXT="muß explizit das ArrayBucket platzieren">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Vorsicht Falle: der Allocator <i>kann das gar nicht machen, </i>wenn man ihm im Sinn von »placement new« explizit die Position vorgibt
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="broken-line"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1718202490965" ID="ID_247674037" MODIFIED="1718297858099" TEXT="Handhabung von non-copyable-Objekten">
|
||||
<linktarget COLOR="#638ad5" DESTINATION="ID_247674037" ENDARROW="Default" ENDINCLINATION="-777;-16;" ID="Arrow_ID_10606647" SOURCE="ID_1146034926" STARTARROW="None" STARTINCLINATION="-438;67;"/>
|
||||
|
|
@ -129709,8 +129819,7 @@ std::cout << tmpl.render({"what", "World"}) << s
|
|||
wenn ein Allocator nur seine eignen Allokationen hanhaben soll ⟹ <b><font size="4">Gefahr</font></b>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head/>
|
||||
<body>
|
||||
|
|
|
|||
Loading…
Reference in a new issue