Какой самый эффективный способ получить доступ к согласованным T & amp; от символа []?

Вчера вечером я работал над этим классом как надёжная оболочка для объектов, выровненных по памяти. У меня есть байтовый массив и математика для доступа к памяти байтового массива для чтения и записи как T, Мне любопытно, однако, как я могу обеспечить наиболее эффективный доступ к согласованным T,

Я пытался использовать публичный T & называется Value который я бы инициализировал к выровненным T в списке инициализатора конструктора. Как это:

template <typename T, size_t alignment = 64>
struct Aligned {
private:
std::uint8_t bytes[sizeof(T) + alignment - 1];
public:
T & Value;
Aligned(T const & value = T()) : Value(*reinterpret_cast<T *>((intptr_t)bytes + (alignment - 1) & ~intptr_t(alignment - 1))) {
Value = value;
}
};

Это увеличивает размер класса на sizeof(T *) поскольку T & Value нужно хранить адрес выровненного T,

Другой мой подход — не хранить адрес, а вычислять его каждый раз, когда требуется доступ, с помощью методов доступа …

#include <array>
#include <cstdint>

template <typename T, size_t alignment = 64>
struct Aligned {
private:
std::array<uint8_t, sizeof(T) + alignment - 1> const bytes;
public:
T const & value() const {
return *reinterpret_cast<T *>((intptr_t)bytes.data() + (alignment - 1) & ~intptr_t(alignment - 1));
}
void value(T const & x) {
*reinterpret_cast<T *>((intptr_t)bytes.data() + (alignment - 1) & ~intptr_t(alignment - 1)) = x;
}
Aligned(T const & x = T()) {
value(x);
}
};

Этот подход потребует арифметику указателя и разыменование указателя (я думаю?) Для каждого доступа, но ничего не добавляет к размеру класса.

Есть ли другие подходы или приемы, чтобы получить оба преимущества?

1

Решение

Я думаю, что вариант 1 выглядит аккуратнее, и я не думаю, что есть какая-то польза от варианта 2.

Однако, если вам нужно знать, что дает вам лучшую производительность, вам действительно нужно выполнить код таким образом, чтобы можно было измерить производительность. Я или кто-то еще, глядя на код и говоря: «А выглядит лучше, чем В», не годится — компиляторы не предсказуемы на 100%, и иногда выбор «Хорошо выглядит» не лучший выбор. Это то, что я говорю о ВСЕХ постах производительности, и для этого есть веская причина. Я лично испытал это, когда вы смотрели на два фрагмента кода, говоря: «Ну, они будут проходить одно и то же время, они почти идентичны», но, поскольку есть небольшая разница, производительность в случае А заметно выше, чем в случае B (или наоборот).

Убедитесь, что вы не просто тестируете здесь тривиальный случай, вам нужно несколько различных вариантов, таких как структура с большим количеством элементов, большой и маленький массив, а также простой int, long long, double, так далее.

1

Другие решения

Если у вас есть доступ к C ++ 11, вы можете использовать новое ключевое слово alignas, чтобы компилятор выровнял тип или переменную для вас.

alignas(64) classA myA;
2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector