64ビット化擬きの真似事の続きの続きの続きの続きです。
取り敢えず、64ビットでの構造体のアラインメントなどを確認するだけのサンプルも作ってみました。
<注意点>
・メモリ効率を上げてシステムのパフォーマンスを改善しようと「#pragma pack」などを使用すると、アラインメントがズレたメンバにアクセスする際に性能低下 *1 を引き起こしたり、最悪の場合バスエラー *2 が発生する恐れがあります。
・前回の32ビットとの違いは、st13~st15の配列の要素数のみです。
*1:インテルの場合、x86系(x64含む) *2:インテルの場合、Itanium系
【64ビット、構造体のアラインメントデータ】
構造体タグ | sizeof | alignment | padding | |||
---|---|---|---|---|---|---|
本来サイズ | 出力結果 | メンバ最大 | 構造体サイズ | メンバ間 | 最終メンバの後 | |
st01 | 9 | 16 | 8 | 16 | 7 | 0 |
st02 | 10 | 16 | 8 | 16 | 6 | 0 |
st03 | 12 | 16 | 8 | 16 | 4 | 0 |
st04 | 16 | 16 | 8 | 16 | 0 | 0 |
st05 | 12 | 16 | 8 | 16 | 4 | 0 |
st06 | 16 | 16 | 8 | 16 | 0 | 0 |
st07 | 9 | 16 | 8 | 16 | 0 | 7 |
st08 | 10 | 16 | 8 | 16 | 0 | 6 |
st09 | 12 | 16 | 8 | 16 | 0 | 4 |
st10 | 16 | 16 | 8 | 16 | 0 | 0 |
st11 | 12 | 16 | 8 | 16 | 0 | 4 |
st12 | 16 | 16 | 8 | 16 | 0 | 0 |
st13 | 17 | 24 | 8 | 24 | 7 | 0 |
st14 | 26 | 32 | 8 | 32 | 6 | 0 |
st15 | 40 | 40 | 8 | 40 | 0 | 0 |
st21 | 10 | 16 | 8 | 16 | 6 | 0 |
st22 | 12 | 16 | 8 | 16 | 4 | 0 |
st23 | 802 | 808 | 8 | 808 | 6 | 0 |
st24 | 804 | 808 | 8 | 808 | 4 | 0 |
お試し環境
WindowsXP 32bit Edition、Windows7 64bit Edition
Visual C++ 2008 cross x64、native x64
/*---- 64ビット ------------------- コマンドライン -----------------------*/
D:\vc2008\x86x64>cl test.c
/*----------------------------------------------------------------------------*/
/*---- 64ビットデータ -------------------- お試し結果 --------------------*/
D:\vc2008\x86x64>test
sizeof check
diz01 = 16, &diz01 = 000000014000FB80, &diz01.no = 000000014000FB80, diz01.dat = 000000014000FB88
diz02 = 16, &diz02 = 000000014000FFE0, &diz02.no = 000000014000FFE0, diz02.dat = 000000014000FFE8
diz03 = 16, &diz03 = 000000014000F800, &diz03.no = 000000014000F800, diz03.dat = 000000014000F808
diz04 = 16, &diz04 = 000000014000FC00, &diz04.no = 000000014000FC00, diz04.dat = 000000014000FC08
diz05 = 16, &diz05 = 000000014000FB70, &diz05.no = 000000014000FB70, diz05.dat = 000000014000FB78
diz06 = 16, &diz06 = 000000014000FBD0, &diz06.no = 000000014000FBD0, diz06.dat = 000000014000FBD8
padding check
diz07 = 16, &diz07 = 000000014000FBF0, diz07.dat = 000000014000FBF0, &diz07.no = 000000014000FBF8
diz08 = 16, &diz08 = 000000014000F820, diz08.dat = 000000014000F820, &diz08.no = 000000014000F828
diz09 = 16, &diz09 = 000000014000FBE0, diz09.dat = 000000014000FBE0, &diz09.no = 000000014000FBE8
diz10 = 16, &diz10 = 000000014000FC20, diz10.dat = 000000014000FC20, &diz10.no = 000000014000FC28
diz11 = 16, &diz11 = 000000014000FC70, diz11.dat = 000000014000FC70, &diz11.no = 000000014000FC78
diz12 = 16, &diz12 = 000000014000FBC0, diz12.dat = 000000014000FBC0, &diz12.no = 000000014000FBC8
Alignment check
diz13 = 24, &diz13 = 000000014000FFC0, &diz13.no = 000000014000FFC0, diz13.dat = 000000014000FFD0
diz14 = 32, &diz14 = 000000014000FBA0, &diz14.no = 000000014000FBA0, diz14.dat = 000000014000FBB8
diz15 = 40, &diz15 = 000000014000FC40, &diz15.no = 000000014000FC40, diz15.dat = 000000014000FC60
Arithmetic check
diz21 = 16, &diz21 = 000000014000F810, &diz21.no = 000000014000F810, diz21.ptr = 000000014000F818
diz22 = 16, &diz22 = 000000014000FC10, &diz22.no = 000000014000FC10, diz22.ptr = 000000014000FC18
diz23 = 808, &diz23 = 000000014000F840, &diz23.no = 000000014000F840, diz23.ptr = 000000014000F848
diz24 = 808, &diz24 = 000000014000FC80, &diz24.no = 000000014000FC80, diz24.ptr = 000000014000FC88
sizeof(WORD) + 100 * sizeof(PVOID) = 802
sizeof(DWORD) + 100 * sizeof(PVOID) = 804
FIELD_OFFSET(struct st21, ptr) + 100 * sizeof(PVOID) = 808
FIELD_OFFSET(struct st22, ptr) + 100 * sizeof(PVOID) = 808
/*----------------------------------------------------------------------------*/
/*---- test.c ------------------- 64ビット お試しソース ------------------*/
#include <stdio.h>
#include <windows.h>
// sizeof check
struct st01 {
char no;
void *dat[1];
} diz01;
struct st02 {
short no;
void *dat[1];
} diz02;
struct st03 {
int no;
void *dat[1];
} diz03;
struct st04 {
long long no;
void *dat[1];
} diz04;
struct st05 {
float no;
void *dat[1];
} diz05;
struct st06 {
double no;
void *dat[1];
} diz06;
// padding check
struct st07 {
void *dat[1];
char no;
} diz07;
struct st08 {
void *dat[1];
short no;
} diz08;
struct st09 {
void *dat[1];
int no;
} diz09;
struct st10 {
void *dat[1];
long long no;
} diz10;
struct st11 {
void *dat[1];
float no;
} diz11;
struct st12 {
void *dat[1];
double no;
} diz12;
// Alignment check
struct st13 {
char no[9];
void *dat[1];
} diz13;
struct st14 {
short no[9];
void *dat[1];
} diz14;
struct st15 {
long long no[4];
void *dat[1];
} diz15;
// Arithmetic check
struct st21 {
WORD no;
PVOID ptr[1];
} diz21;
struct st22 {
DWORD no;
PVOID ptr[1];
} diz22;
struct st23 {
WORD no;
PVOID ptr[100];
} diz23;
struct st24 {
DWORD no;
PVOID ptr[100];
} diz24;
int main(int argc, char *argv[])
{
printf("sizeof check\n");
printf("diz01 = %d, &diz01 = %p, &diz01.no = %p, diz01.dat = %p\n", sizeof(diz01), &diz01, &diz01.no, diz01.dat);
printf("diz02 = %d, &diz02 = %p, &diz02.no = %p, diz02.dat = %p\n", sizeof(diz02), &diz02, &diz02.no, diz02.dat);
printf("diz03 = %d, &diz03 = %p, &diz03.no = %p, diz03.dat = %p\n", sizeof(diz03), &diz03, &diz03.no, diz03.dat);
printf("diz04 = %d, &diz04 = %p, &diz04.no = %p, diz04.dat = %p\n", sizeof(diz04), &diz04, &diz04.no, diz04.dat);
printf("diz05 = %d, &diz05 = %p, &diz05.no = %p, diz05.dat = %p\n", sizeof(diz05), &diz05, &diz05.no, diz05.dat);
printf("diz06 = %d, &diz06 = %p, &diz06.no = %p, diz06.dat = %p\n", sizeof(diz06), &diz06, &diz06.no, diz06.dat);
printf("\npadding check\n");
printf("diz07 = %d, &diz07 = %p, diz07.dat = %p, &diz07.no = %p\n", sizeof(diz07), &diz07, diz07.dat, &diz07.no);
printf("diz08 = %d, &diz08 = %p, diz08.dat = %p, &diz08.no = %p\n", sizeof(diz08), &diz08, diz08.dat, &diz08.no);
printf("diz09 = %d, &diz09 = %p, diz09.dat = %p, &diz09.no = %p\n", sizeof(diz09), &diz09, diz09.dat, &diz09.no);
printf("diz10 = %d, &diz10 = %p, diz10.dat = %p, &diz10.no = %p\n", sizeof(diz10), &diz10, diz10.dat, &diz10.no);
printf("diz11 = %d, &diz11 = %p, diz11.dat = %p, &diz11.no = %p\n", sizeof(diz11), &diz11, diz11.dat, &diz11.no);
printf("diz12 = %d, &diz12 = %p, diz12.dat = %p, &diz12.no = %p\n", sizeof(diz12), &diz12, diz12.dat, &diz12.no);
printf("\nAlignment check\n");
printf("diz13 = %d, &diz13 = %p, &diz13.no = %p, diz13.dat = %p\n", sizeof(diz13), &diz13, &diz13.no, diz13.dat);
printf("diz14 = %d, &diz14 = %p, &diz14.no = %p, diz14.dat = %p\n", sizeof(diz14), &diz14, &diz14.no, diz14.dat);
printf("diz15 = %d, &diz15 = %p, &diz15.no = %p, diz15.dat = %p\n", sizeof(diz15), &diz15, &diz15.no, diz15.dat);
printf("\nArithmetic check\n");
printf("diz21 = %d, &diz21 = %p, &diz21.no = %p, diz21.ptr = %p\n", sizeof(diz21), &diz21, &diz21.no, diz21.ptr);
printf("diz22 = %d, &diz22 = %p, &diz22.no = %p, diz22.ptr = %p\n", sizeof(diz22), &diz22, &diz22.no, diz22.ptr);
printf("diz23 = %d, &diz23 = %p, &diz23.no = %p, diz23.ptr = %p\n", sizeof(diz23), &diz23, &diz23.no, diz23.ptr);
printf("diz24 = %d, &diz24 = %p, &diz24.no = %p, diz24.ptr = %p\n", sizeof(diz24), &diz24, &diz24.no, diz24.ptr);
printf("\n");
printf("sizeof(WORD) + 100 * sizeof(PVOID) = %d\n", sizeof(WORD) + 100 * sizeof(PVOID));
printf("sizeof(DWORD) + 100 * sizeof(PVOID) = %d\n", sizeof(DWORD) + 100 * sizeof(PVOID));
printf("FIELD_OFFSET(struct st21, ptr) + 100 * sizeof(PVOID) = %d\n", FIELD_OFFSET(struct st21, ptr) + 100 * sizeof(PVOID));
printf("FIELD_OFFSET(struct st22, ptr) + 100 * sizeof(PVOID) = %d\n", FIELD_OFFSET(struct st22, ptr) + 100 * sizeof(PVOID));
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*============================================================================*/