#c #c 11 #memory-alignment
Вопрос:
Правильно ли, что я рассматриваю std::align
вычисление адреса во время выполнения в соответствии с дальнейшей логикой моей программы, т. Е. Если логика программы не учитывает какое-либо конкретное выравнивание, его не имеет смысла использовать std::align
?
Влияет ли использование of std::align
на генерацию кода? Правильно ли я понимаю, что, в отличие std::assume_aligned
от C 20, std::align
это не подсказка компилятору?
Комментарии:
1. Как конкретно вы используете
std::align
? Если вы сами не управляете памятью, она вам не нужна.2. Я не совсем понимаю вопрос. Возможно, вы думаете об элайнасе ?
Ответ №1:
std::align
это обычная бесплатная функция. Это не подсказка компилятора, в этом нет никакой магии. Это влияет на генерацию кода, как любая другая функция, возможно, влияет на генерацию кода, т. Е. Она может быть встроена, переупорядочена и т.д., Но не каким-либо определенным образом.
Относительно того, что делает функция и когда она используется (ссылка cpp):
Учитывая указатель ptr на буфер пространства размера, возвращает указатель, выровненный по указанному выравниванию для количества байтов размера, и уменьшает аргумент пространства на количество байтов, используемых для выравнивания. Возвращается первый выровненный адрес.
Таким образом, это конструкция времени выполнения, которая выполняет некоторую арифметику указателей, чтобы вернуть адрес, который можно использовать для желаемого выравнивания. Представьте, что вы хотите сохранить a std::int64_t
по какому-то адресу памяти, но вы не знаете, правильно ли он выровнен (потому что он находится в середине какого-то выделенного буфера std::malloc
), тогда std::align
это ваш друг.
Вот реализация libstdcxx:
inline void*
align(size_t __align, size_t __size, void*amp; __ptr, size_tamp; __space) noexcept
{
if (__space < __size)
return nullptr;
const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
const auto __aligned = (__intptr - 1u __align) amp; -__align;
const auto __diff = __aligned - __intptr;
if (__diff > (__space - __size))
return nullptr;
else
{
__space -= __diff;
return __ptr = reinterpret_cast<void*>(__aligned);
}
}
Он используется, например, в std::monotonic_buffer_resource::do_allocate
— именно для такого случая использования была создана эта функция.