2016-03-26 2 views
6

При чтении this Я был поражен тем, что определенный уровень метапрограммирования может сделать для вашего класса. Я должен признать, что я не в полной мере понять, что предлагаемое оптимальное расположение, если бы я должен был заявить, что я понял, что это будет так:У реализации кортежа есть оптимизированная компоновка?

член класса упорядочение по убыванию выравнивания т.е. типа с наибольшей alignof результат идет первый и т.д.

вы можете исправить меня, если я получил это неправильно (если у вас есть краткое объяснение того, почему это происходит, было бы еще лучше, я не мог копировать вставить большие куски обоснование в моем вопросе) , но мой вопрос касается другой темы:

Есть ли такая реализация библиотеки в std::tuple?

Если нет, существуют ли какие-либо стандартные типы алгебраических данных, есть ли другой способ сделать это для моего класса, помимо написания такого механизма?

ответ

9

Нет реализации библиотеки. Я знаю, что оптимизирует компоновку для выравнивания. Вы можете использовать такие программы, как это инспектировать tuple расположения:

#include <iostream> 
#include <tuple> 

struct empty {}; 

int 
main() 
{ 
    using T = std::tuple<double, int, empty, short, long>; 
    T t{}; 
    std::cout << &t << '\n'; 
    std::cout << &std::get<0>(t) << '\n'; 
    std::cout << &std::get<1>(t) << '\n'; 
    std::cout << &std::get<2>(t) << '\n'; 
    std::cout << &std::get<3>(t) << '\n'; 
    std::cout << &std::get<4>(t) << '\n'; 
    std::cout << &t+1 << '\n'; 
    std::cout << sizeof(T) << '\n'; 
} 

LibC++ хранит элементы в порядке объявления, и оптимизирует пространство прочь для пустых элементов. Пустые члены шунтируются в направлении фронта. Пример вывода:

0x7fff5ccf39f8 
0x7fff5ccf39f8 
0x7fff5ccf3a00 
0x7fff5ccf39f8 
0x7fff5ccf3a04 
0x7fff5ccf3a08 
0x7fff5ccf3a10 
24 

libstdC++ хранит элементы в обратном порядке объявления, и оптимизирует пространство прочь для пустых элементов. Пустые члены шунтируются в направлении фронта. Выход проб:

0x7ffe4fc5b2a0 
0x7ffe4fc5b2b0 
0x7ffe4fc5b2ac 
0x7ffe4fc5b2a0 
0x7ffe4fc5b2a8 
0x7ffe4fc5b2a0 
0x7ffe4fc5b2b8 
24 

VS-2015 сохраняет элементы в обратном порядке декларации и не оптимизирует пространство для пустых элементов. Пример вывода:

0306FEF4 
0306FF04 
0306FF00 
0306FEFC 
0306FEF8 
0306FEF4 
0306FF0C 
24 

В этом примере мы видим, что оптимизация пространства прочь для пустого элемента ничего не покупать, так как он подходит в области прокладки в любом случае.

Нет никаких средств, которые автоматизируют задачу уменьшения заполнения в стандарте.

+0

Не могли бы вы рассказать о том, почему упорядочение по нисходящей настройке было бы оптимальным вариантом? –

+0

@LorahAttkins: Это эвристика, которая часто работает. Он предполагает, что сам класс обычно максимально выровнен, поэтому поэтому ваши максимально согласованные члены сначала не гарантируют отсутствие байтов заполнения между вашими максимально выровненными членами. Затем переходите к следующим самым большим членам выравнивания и придерживайтесь той же логики. Когда у вас заканчиваются члены, у вас обычно будет добавление дополнительных слов, чтобы округлить sizeof (your_class) до кратного выравнивания класса. Поэтому иногда трюк order-by-align сэкономит вам байты, а иногда и не будет. Это хороший инструмент для работы с инструментами. –

+0

Я должен был добавить к моему комментарию выше: размер каждого типа кратен выравниванию для этого типа. Например, нет такой вещи, как тип с выравниванием по 16 байт и sizeof 15 или 17. Его sizeof будет 16 или 32 или 48 и т. Д. Это означает, что и '& a' *, и' 'и a + 1', являются указателями с выравниванием как наименее значимыми, как 'alignof (a)'. –