本地类型如何总是获得偶数地址 [英] How come local types always get an even address

查看:50
本文介绍了本地类型如何总是获得偶数地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出示例代码:

void func( char arg)
{
    char a[2];
    char b[3];
    char c[6];
    char d[5];
    char e[8];
    char f[13];
    std::cout << (int)&arg << std::endl;
    std::cout << (int)&a << std::endl;
    std::cout << (int)&b << std::endl;
    std::cout << (int)&c << std::endl;
    std::cout << (int)&d << std::endl;
    std::cout << (int)&e << std::endl;
    std::cout << (int)&f << std::endl;
}

在每次通话中,我得到的结果类似于以下内容:

How comes that with every call i get a result similar to that:

3734052
3734048
3734044
3734080
3734088
3734072
3734056

每个地址都是偶数吗?为什么地址的顺序与代码中的变量不同?

With every address being an even number? And why are the addresses not in the same order like the variables are in the code?

推荐答案

为什么地址不像变量那样以相同的顺序排列在代码中?

And why are the addresses not in the same order like the variables are in the code?

保证结构中的第一个元素与结构本身在同一位置(如果它们是一个元素的成员),但不保证其他元素以任何顺序排列.编译器将适当地对它们进行排序,以使其通常使用最少的空间.对于局部变量,它们在内存中的位置完全取决于编译器.它们可能都在同一个区域中(可能是因为它会利用局部性),或者它们可能遍布整个地图(如果您使用笨拙的编译器).

The first element in the structure is guaranteed to be at the same location as the structure itself (if they were members of one), but the other elements are not guaranteed to be in any order. The compiler will order them appropriately to allow it to use the least amount of space, typically. For local variables, where they are located in memory is completely up to the compiler. They could all be in the same area (likely since it would take advantage of locality), or they could be all over the map (if you have a crappy compiler).

每个地址都是偶数吗?

With every address being an even number?

它将它们沿单词边界放置.与不将它们放置在单词边界上相比,这使内存访问速度更快.例如,如果将 a 放在一个单词的最后一个字节上,另一个单词的第一个字节上:

It is placing them along word boundaries. This makes memory access faster than if they are not placed on word boundaries. For example, if a were to be placed on the last byte of one word, and the first byte of another:

|             WORD 1                |                WORD 2             |
|--------|--------|--------|--------|--------|--------|--------|--------|
                           |  a[0]  |  a[1]  |

然后访问 a [0] 然后访问 a [1] 将需要将2个单词加载到高速缓存中(每个高速缓存都未命中).通过沿单词边界放置

Then accessing a[0] and then a[1] would require loading 2 words into the cache (on a cache miss for each). By placing a along a word boundary:

|             WORD 1                |
|--------|--------|--------|--------|
|  a[0]  |  a[1]  |

a [0] 上的缓存未命中会导致同时加载 a [0] a [1] 时间(减少不必要的内存带宽).这利用了局部性原则.尽管该语言当然不需要它,但这是编译器完成的非常常见优化(除非您使用预处理程序指令来阻止它).

A cache miss on a[0] would result in both a[0] and a[1] being loading at the same time (decreasing the unnecessary memory bandwidth). This takes advantage of the principle of locality. While it is certainly not required by the language, it is a very common optimization done by compilers (unless you use preprocessor directives to prevent it).

在您的示例中(按其顺序显示):

In your example (shown in their order):

3734044 b[0]
3734045 b[1]
3734046 b[2]
3734047 -----
3734048 a[0]
3734049 a[1]
3734050 -----
3734051 -----
3734052 arg
3734053 -----
3734054 -----
3734055 -----
3734056 f[0]
3734057 f[1]
3734058 f[2]
3734059 f[3]
3734060 f[4]
3734061 f[5]
3734062 f[6]
3734063 f[7]
3734064 f[8]
3734065 f[9]
3734066 f[10]
3734067 f[11]
3734068 f[12]
3734069 -----
3734070 -----
3734071 -----
3734072 e[0]
3734073 e[1]
3734074 e[2]
3734075 e[3]
3734076 e[4]
3734077 e[5]
3734078 e[6]
3734079 e[7]
3734080 c[0]
3734081 c[1]
3734082 c[2]
3734083 c[3]
3734084 c[4]
3734085 c[5]
3734086 -----
3734087 -----
3734088 d[0]
3734089 d[1]
3734090 d[2]
3734091 d[3]
3734092 d[4]

假设没有其他数据分配给这些孔,那么您使用编译器进行的任何设置都会显示出来,以确保所有数组均以字边界开头.不是在数组之间增加空间(您可以看到 e c 之间没有空间),但是第一个元素必须位于字边界.这是特定于实现的,完全不是标准要求的.

Assuming no other data is being assigned to those holes, it would appear whatever settings you have with your compiler is making sure that all of your arrays start on a word boundary. It isn't that it is adding space between the arrays (as you can see there is no space between e and c), but that the first element must be on a word boundary. This is implementation specific and not at all required by the standard.

这篇关于本地类型如何总是获得偶数地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆