Giriş
Açıklaması şöyle. Bu new operator'un overload hali C++17 ile geliyor
Örnek
Elimizde şöyle bir kod olsun. Bu yapı 16 byte yani 128 bitlik register'lara sığar
Elimizde şöyle bir kod olsunn
Şöyle yaparız
Açıklaması şöyle. Bu new operator'un overload hali C++17 ile geliyor
_aligned_malloc() is a Windows-specific, non-portable function. Luckily, C++17 added the portable aligned_alloc() without an underscore. It also introduces a variant of new that allows aligned allocation.Bu Özellik Neden Lazım
Örnek
Elimizde şöyle bir kod olsun. Bu yapı 16 byte yani 128 bitlik register'lara sığar
struct alignas(16) Vec3 {
float x, y, z;
};
Açıklaması şöyleWhy might you need those functions? It’s because if you have some specific types, like a Vec3 that has to be allocated to 128bits alignment (so it can fit nicely in SIMD registers),Bu yapıyı new'leyelim
auto ptr = new Vec3[10];
Ama C++14 ile karşımıza şu problem çıkıyor.To work with SSE you require the ptr to be aligned to 16-byte boundary, but in C++14 there’s no guarantee about this.C++17 bu problemi çözüyor. Açıklaması şöyle
ÖrnekFortunately, the C++17 standard fixes this by introducing allocation functions that honour the alignment of the object.For example we have:void* operator new[](std::size_t count, std::align_val_t al);
Now, when you allocate an object that has a custom alignment, then you can be sure it will be appropriately aligned.
Elimizde şöyle bir kod olsunn
#include <cassert>
#include <cstdint>
#include <iostream>
#include <malloc.h>
#include <new>
class alignas(32) Vec3d {
double x, y, z;
};
int main() {
std::cout << "sizeof(Vec3d) is " << sizeof(Vec3d) << '\n';
std::cout << "alignof(Vec3d) is " << alignof(Vec3d) << '\n';
auto Vec = Vec3d{};
auto pVec = new Vec3d[10];
if(reinterpret_cast<uintptr_t>(&Vec) % alignof(Vec3d) == 0)
std::cout << "Vec is aligned to alignof(Vec3d)!\n";
else
std::cout << "Vec is not aligned to alignof(Vec3d)!\n";
if(reinterpret_cast<uintptr_t>(pVec) % alignof(Vec3d) == 0)
std::cout << "pVec is aligned to alignof(Vec3d)!\n";
else
std::cout << "pVec is not aligned to alignof(Vec3d)!\n";
delete[] pVec;
}
Açıklaması şöyleThe code shows a structure - Vec3d that uses three double fields; it also marks the type with alignas that makes the objects aligned to 32 bytes.C++14 ile çıktı olarak şunu alırız
Then the example creates two objects: one on the stack and one on the free store.
Do they both have the same alignment (32 bytes)?
And another question:
Should you care about the alignment of your memory allocations?
sizeof(Vec3d) is 32C++17 ile çıktı olarak şunu alırız
alignof(Vec3d) is 32
Vec is aligned to alignof(Vec3d)!
pVec is not aligned to alignof(Vec3d)!
Açıklaması şöylesizeof(Vec3d) is 32alignof(Vec3d) is 32
Vec is aligned to alignof(Vec3d)!
pVec is aligned to alignof(Vec3d)!
In both compiler results, the alignment of objects on the stack is 32, as expected.Örnek
But for dynamic allocation it’s different:
In C++11 and C++14, there was no guarantee that memory allocated for types that are over-aligned honours that specific alignment. In our case we want Vec3d allocations to return pointers that are 32-byte aligned… but GCC 4.8.5 allocates differently.
How about C++17?
Now, in the newest standard, we have updated dynamic memory allocations, and now we have a guarantee that the memory will be aligned as requested.
As you see in GCC 9.1, the memory is now 32-byte aligned.
Şöyle yaparız
#include <new>
...
MemoryBlock::MemoryBlock(size_t size, size_t alignment):
p_rawMem((void *)new(std::align_val_t(alignemnt)) char[size]),
...
{
}
Hiç yorum yok:
Yorum Gönder