Какой самый маленький размер я могу сделать эту структуру на 64-битной машине? - PullRequest
5 голосов
/ 30 ноября 2011
typedef struct node{
    char one;
    char two;
    struct node *next;
} nodea;

Я думаю с точки зрения заполнения компилятора, есть ли способ сделать sizeof (nodea) меньше 16?

Ответы [ 5 ]

5 голосов
/ 30 ноября 2011

Если это не что-то необычное, его можно упаковать в 1 + 1 + 8 = 10 байт. Если указатели должны быть выровнены, то 16 байтов. Если сначала поставить указатель, а затем символ, затем 10 байт, но требования к выравниванию все равно могут составить 16, когда вы создаете массив этих структур.

5 голосов
/ 30 ноября 2011

Вы можете использовать директиву компилятора #pragma pack http://msdn.microsoft.com/en-us/library/2e70t5y1%28v=vs.80%29.aspx

 #pragma pack(push)
 #pragma pack(1)
 typedef struct node {
    char one;
    char two;
    struct node* next;
 } nodea;
 #pragma pack(pop)
4 голосов
/ 30 ноября 2011

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

Как повлиять на упаковку, зависит от вашего компилятора, но большинство компиляторов, включая gcc , поддерживают директивы типа #pragma pack.

1 голос
/ 30 ноября 2011

Это зависит от компилятора.Обычно вы можете контролировать выравнивание структурных полей / переменных.Например, с помощью gcc вы можете использовать

typedef struct __attribute__ ((packed)) node {
    char one;
    char two;
    struct node *next;
} nodea;

, чтобы получить 10 для sizeof(nodea) на 64-битной платформе.

0 голосов
/ 30 ноября 2011

Использование упакованного в структуре также означает, что компилятор не может переупорядочить структуру данных, на некоторых платформах упаковка может привести к значительному снижению производительности. Некоторые процессоры не могут получить невыровненные слова, поэтому, если код будет скомпилирован на этой платформе, компилятор будет вынужден получать слово за байт и перемещать все в нужное место, это определенно то, что вам не нужно. Особенно в связанном списке, так как это сделает ваш список действительно очень медленным к доступу ... И даже если процессор поддерживает выравнивание, получение ЦП потребует дополнительных циклов для чтения из 2 адресов в памяти и повторного их объединения.

Вот почему вы должны посмотреть, как вы можете помочь компилятору. Вы бы хотели, чтобы структура выровнялась по словам, чтобы адрес следующего узла всегда можно было прочитать с помощью одной инструкции чтения. Это означало бы, что для 64-битной архитектуры вы бы хотели разместить указатель следующего узла сверху, чтобы он всегда был выровнен, затем вам нужно убедиться, что если вы используете структуры в массиве, адрес struct node * будет всегда выравнивайте, поэтому вам нужно убедиться, что ваш окончательный размер структуры кратен 8 байтам. Это означает, что вы можете добавить еще 6 элементов или выбрать больший тип данных.

Это будет означать, что вы получите что-то вроде этого:

typedef struct __attribute__((packed)) node {
    struct node *next;
    char data[8];
} nodea;

typedef struct __attribute__((packed)) node {
    struct node *next;
    uint16_t data[4];
} nodea;

typedef struct __attribute__((packed)) node {
    struct node *next;
    uint32_t data[2];
} nodea;

и т.д.. и т. д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...