What is memory to Qi (Save)

xiaoxiao2021-03-06  77

Quote:

Original author name fang

text

What is memory alignment

Consider the following structure:

Struct foo

{

CHAR C1;

Short S;

CHAR C2;

INT I;

}

Assuming that the member of this structure is compactly arranged in memory. It is assumed that the address of the C1 is 0, then the address of S should be 1, the address of C2 is 3, i's address is 4. That is

C1 00000000, S 00000001, C2 00000003, i 00000004.

However, we write a simple program in Visual C / C 6:

Struct foo a;

Printf ("C1% P, S% P, C2% P, I% P / N",

(unsigned int) & a.c1 - (unsigned int) (void *) & A,

(unsigned int) & a.s - (unsigned int) & A,

(unsigned int) & a.c2 - (unsigned int) (void *) & A,

(unsigned int) & a.i - (unsigned int) (void *) & a);

Run, output:

C1 00000000, S 00000002, C2 00000004, i 00000008.

Why is this this? This is the problem caused by memory alignment.

Why do there be memory?

The following segments are selected from "Intel Architecture 32 Manual".

Words, double words, and quad words do not need to be aligned in memory on the natural boundary. (For words, double words, and four words, the natural boundaries are even addresses, which can be 4 complete addresses, and the address that can be completely removed.)

In any case, in order to improve the performance of the program, the data structure (especially the stack) should be aligned on the natural boundary as much as possible. The reason is that in order to access unsigned memory, the processor needs two memory access; however, the aligned memory access only needs to be accessed.

A word or double word operance spans the 4-byte boundary, or a four-character operand spans the 8-byte boundary, which is considered to be unsigned, which requires two bus cycles to access memory. A word start address is an odd number but there is no leapfrog that is considered to be aligned, and can be accessed in a bus cycle.

Some operational double four words require memory operations to align in the natural boundary. If the operand is not aligned, these instructions will generate a universal protection exception (#GP). The natural boundary of the double four word is the address that can be tied to the 16. Other operational double four words allow unconfigured access (no universal protection exception), however, additional memory bus cycles are required to access unsigned data in memory.

The compiler is processed by memory

By default, the C / C compiler defaults to the structure and the member data in the stack. Therefore, the above program output is turned:

C1 00000000, S 00000002, C2 00000004, i 00000008.

The compiler will move the unsigned member to the backward, and each member is aligned to the natural boundary, which has also caused the size of the entire structure to be large. Although it will sacrifice a little space (there is a void between members), performance is improved.

It is also this reason, we can't assert SIZEOF (FOO) == 8. In this example, SIZEOF (FOO) == 12.

How to avoid the impact of memory

So, can you achieve the purpose of improving performance, save a little space? There is a little tip that can be used. For example, we can change the structure above: Struct Bar

{

CHAR C1;

CHAR C2;

Short S;

INT I;

}

In this way, each member is aligned with its natural boundary, thereby avoiding the auto-alignment of the compiler. In this example, SizeOf (BAR) == 8.

This tip has an important role, especially when this structure is provided to third parties as part of the API. Third-party developers may change the default alignment option of the compiler to cause this structure to use some alignment in your released DLL, and where to use another alignment in the third party developer. This will lead to major problems.

For example, the FOO structure, our DLL uses the default alignment option, aligned

C1 00000000, S 00000002, C2 00000004, i 00000008, while SIZEOF (FOO) == 12.

The third party will close the alignment, resulting in

C1 00000000, S 00000001, C2 00000003, i 00000004, while SIZEOF (FOO) == 8.

How to use alignment options in C / C

The compilation options in the VC6 are / zp [1 | 2 | 4 | 8 | 16], / zp1 indicates that the 1-byte boundary is aligned, corresponding, / ZPN is aligned in the n-byte boundary. The N-byte boundary is aligned. The address of a member must be arranged on an integer multiple of the member's size or an integer multiple of N to take the minimum of them. That is:

MIN (Sizeof (Member), N)

In fact, the 1-byte boundary is aligned with no hollow between structural members.

The / ZPN option is applied to the entire project, affecting all the structures involved in compilation.

To use this option, you can open the engineering property page, C / C page in VC6, select the Code Generation classification, and select it in Struct Member Alignment.

To use the alignment option specifically for some structural definitions, you can use the #pragma Pack to compile instructions. The instruction syntax is as follows:

#pragma pack ([show] | [Push | POP] [, Identifier], N)

Significance and / ZPN options are the same. such as:

#pragma pack (1)

Struct foo_pack

{

CHAR C1;

Short S;

CHAR C2;

INT I;

}

#pragma pack ()

Stack memory

We can observe that alignment in the stack in VC6 is not affected by structural members alignment options. (Or two is two yards). It always remains aligned, and is aligned on the 4-byte boundary

转载请注明原文地址:https://www.9cbs.com/read-95488.html

New Post(0)