В книге Game Coding Complete, 3rd Edition, автор упоминает технику, позволяющую как уменьшить размер структуры данных так и увеличить производительность доступа. По сути, он основан на том факте, что вы выигрываете в производительности, когда переменные-члены выравниваются по памяти. Это очевидная потенциальная оптимизация, которой компиляторы могли бы воспользоваться, но, убедившись, что каждая переменная выровнена, они в итоге увеличивают размер структуры данных.
По крайней мере, так он утверждает.
Реальное увеличение производительности, по его словам, достигается за счет использования мозгов и обеспечения правильного проектирования структуры, чтобы воспользоваться преимуществами увеличения скорости и в то же время предотвратить раздувание компилятора. Он приводит следующий фрагмент кода:
#pragma pack( push, 1 )
struct SlowStruct
{
char c;
__int64 a;
int b;
char d;
};
struct FastStruct
{
__int64 a;
int b;
char c;
char d;
char unused[ 2 ]; // fill to 8-byte boundary for array use
};
#pragma pack( pop )
Используя приведенные выше объекты struct
в неуказанном тесте, он сообщает о приросте производительности на 15,6%
(222мс
по сравнению с 192мс
) и меньшем размере для FastStruct
. Все это имеет смысл на бумаге, но не подтверждается моими тестами:
Одинаковые результаты времени и размера (считая для char unused[ 2 ]
)!
Теперь, если #pragma pack( push, 1 )
изолировать только для FastStruct
(или убрать совсем), мы действительно видим разницу:
Итак, наконец, вопрос: Действительно ли современные компиляторы (в частности VS2010) уже оптимизируют выравнивание битов, отсюда и отсутствие прироста производительности (но увеличение размера структуры как побочный эффект, как заявил Mike Mcshaffry)? Или мой тест недостаточно интенсивен/неубедителен, чтобы получить значимые результаты?
Для тестов я выполнял различные задачи, начиная от математических операций, обхода/проверки многомерных массивов по столбцам, матричных операций и т.д. на невыровненном члене __int64
. Ни одна из этих операций не привела к различным результатам для любой структуры.
В итоге, даже если прироста производительности не было, это все равно полезная информация, которую стоит иметь в виду, чтобы свести использование памяти к минимуму. Но я был бы рад, если бы был прирост производительности (неважно, насколько незначительный), которого я просто не вижу.