Расскажите про реальные минусы, плюсы. Подводные камни.
Ну упаковали мы структуру, ну стала она меньше памяти занимать. Как бы всё. Но допустим мы не экономим на памяти (допустим!) если ещё реальный смысл паковать? Где-то говорят что промахи кеша уменьшаются и от того код работает быстрее ведь как следствие конвеер не перезапускается, но я не верю.
UDP: На заметку (Всем спасибо за советы! (•◡•)/ )
Утилита pahole для выявления дыр в структурах и их реорганизации в Debian утилита доступна из пакета dwarves sudo apt install dwarves
gcc/clang c опцией -g3 -Wpadded + -Wextra -Wall -Werror не пропустят код с дырявыми структурами
Например для такой структуры
typedef struct {
  bool collided;
  float time;
  vec3 point;
  vec3 norm;
  int flags;
} collision;
Clang выдаёт чуть более информативно
./include/physics.h:13:9: error: padding struct 'collision' with 3 bytes to align 'time' [-Werror,-Wpadded]
  float time;
GCC же просто указывает на предмет «проблемы»
./include/physics.h:13:9: error: padding struct to align ‘time’ [-Werror=padded]
   float time;
         ^~~~
Прогон pahole же при компиляции с -g3 даёт чёткое указание на «проблему»
ничего :D
И это «ничего» меня поставило в ступор сначала, но дело в том что я использую typedef и по какой то причине
pahole игнорирует не именованные структуры, если исправить так
typedef struct collision{
  bool collided;
  float time;
  vec3 point;
  vec3 norm;
  int flags;
} collision;
То pahole выдаёт чёткие подробности
struct collision {
	_Bool                      collided;             /*     0     1 */
	/* XXX 3 bytes hole, try to pack */
	float                      time;                 /*     4     4 */
	vec3                       point;                /*     8    12 */
	vec3                       norm;                 /*    20    12 */
	int                        flags;                /*    32     4 */
	/* size: 36, cachelines: 1, members: 5 */
	/* sum members: 33, holes: 1, sum holes: 3 */
	/* last cacheline: 36 bytes */
};
Исправление на
typedef struct collision {
  vec3  point;
  vec3  norm;
  float time;
  int   flags;
  bool  collided;
} collision;
Убирает предупреждения/ошибки из gcc/clang, а pahole репортует что в целом всё впорядке
struct collision {
	vec3                       point;                /*     0    12 */
	vec3                       norm;                 /*    12    12 */
	float                      time;                 /*    24     4 */
	int                        flags;                /*    28     4 */
	_Bool                      collided;             /*    32     1 */
	/* size: 36, cachelines: 1, members: 5 */
	/* padding: 3 */
	/* last cacheline: 36 bytes */
};
Но, для полного счастья было бы хорошо заполнить 3 байта для выравнивания структур (массивы структур или дву/одно связные списки к примеру) в данном случае можно заменить bool на int или добавить заполнение char pad[3] если изменение типа структуры выливается в геморой ползания по коду или нарушает читабельность.
При окончательном изменении на
typedef struct collision {
  vec3  point;
  vec3  norm;
  float time;
  int   flags;
  bool  collided;
  char  __unused_struct_padding__[3];
} collision;
получаем репорт от pahole что всё ok
struct collision {
	vec3                       point;                /*     0    12 */
	vec3                       norm;                 /*    12    12 */
	float                      time;                 /*    24     4 */
	int                        flags;                /*    28     4 */
	_Bool                      collided;             /*    32     1 */
	char                       __unused_struct_padding__[3]; /*    33     3 */
	/* size: 36, cachelines: 1, members: 6 */
	/* last cacheline: 36 bytes */
};
Заполнять пустотой это конечно такое себе, но зато на будущее есть понимание что практически бесплатно можно будет в эту структуру засунуть ещё три флага например, таким образом использовать для дела в пустую в данном случае гоняемую память.
Ну вот как то так.









