Giriş
Bu yapı ile iki tane aynı nesneyi yanyana koyarsak ne kadar hizalama belleği kullanılacağını belirtiriz.
array
Şöyle yaparız.
Örnek
Bu yapı ile iki tane aynı nesneyi yanyana koyarsak ne kadar hizalama belleği kullanılacağını belirtiriz.
array
Şöyle yaparız.
typedef unsigned char Type;
const int N = 4;
alignas(64) Type buffer[N*64];
structÖrnek
Şöyle yaparız.
Primitive
Şöyle yaparız.
Şöyle yaparız
Örnek
Önce align edilmiş bir bellek alanı hazırlarız.
Şöyle yaparız. Burada bellek alanı olarak daha büyük bir yer veriliyor.
struct alignas(16) small16 {
char c;
};
Örnek
Elimizde şöyle bir kod olsun. Derleyici optimizedEqual() ve optimizedEqual2() kodları için hızlı kod üretiyor. Yani std::memcpy() ve std::memcmp() hızı çalışıyor. Ancak alanları tek tek karşılaştırma kodları hızlı değil.
struct Point {
std::int32_t x, y;
};
[[nodiscard]]
bool naiveEqual(const Point &a, const Point &b) {
return a.x == b.x && a.y == b.y;
}
[[nodiscard]]
bool optimizedEqual(const Point &a, const Point &b) {
// Why can't the compiler produce the same assembly in naiveEqual as it does here?
std::uint64_t ai, bi;
static_assert(sizeof(Point) == sizeof(ai));
std::memcpy(&ai, &a, sizeof(Point));
std::memcpy(&bi, &b, sizeof(Point));
return ai == bi;
}
[[nodiscard]]
bool optimizedEqual2(const Point &a, const Point &b) {
return std::memcmp(&a, &b, sizeof(a)) == 0;
}
[[nodiscard]]
bool naiveEqual1(const Point &a, const Point &b) {
// Let's try avoiding any jumps by using bitwise and:
return (a.x == b.x) & (a.y == b.y);
}
Düzeltmek için şöyle yaparız. Point sınıfı 64 bit olacak şekilde hizalanırsa yani varsa aradaki "data alignment" byte'ları kaldırılırsa, derleyici 64 bşt karşılaştırma yapabilir.
struct alignas(std::int64_t) Point {
std::int32_t x, y;
};
Şöyle yaparız.
alignas(64) double bar;
Gcc ExtensionŞöyle yaparız
typedef uint32_t __attribute__ ((aligned (64))) aligned_uint32_t;
std::cout << sizeof(aligned_uint32_t) << " -> " << alignof(aligned_uint32_t);
// Output: 4 -> 64
placement newÖrnek
Önce align edilmiş bir bellek alanı hazırlarız.
alignas(Foo) char memory[sizeof(Foo)];
Neden bilmiyorum ancak şu kullanım yanlış.char memory[sizeof(Foo)];
Sonra placement new kullanarak şöyle yaparız.
::new (static_cast<void*>(buf)) Foo;
ÖrnekŞöyle yaparız. Burada bellek alanı olarak daha büyük bir yer veriliyor.
alignas(int) unsigned char buffer[2*sizeof(int)];
auto p1=new(buffer) int{};
Hiç yorum yok:
Yorum Gönder