结构尺寸优化

时间:2015-04-11 21:18:57

标签: c structure

我有一个可以运行32位或64位的系统。如果我定义一个包含7个long和1个char的结构,那么我理解如果结构在32位上运行,则long将被分配32位,char将被分配8位,并且该结构将需要至少232位。但是如果结构在64位上运行,则long将被分配64位,char将被分配8位,并且该结构将需要至少456位。我也理解,如果结构需要2位的功率,则存储器将针对结构的阵列进行优化。然后,该结构必须在32位系统上填充256位或在64位系统上填充512位。是否会自动将填充添加到结构中以优化内存,或者我应该在结构中添加一些内容以使其更接近2位的功率以优化这些结构阵列的处理?

2 个答案:

答案 0 :(得分:1)

编辑:刚刚看到有关使用轮播与乘法进行数组索引的文章。我的建议是根据您的数据适当调整结构大小,如果您能提供帮助,请注意不要浪费空间。如果探查器确定索引元素是您的主要性能影响,您可以尝试添加slop 以专门达到特定的字节大小。但是,我的直觉告诉我(在一个带有缓存的现代系统上),你会因为不必要地增加结构的大小并将有用的内存从缓存中推出而遭受更大的性能损失!:D

(原始回复如下)

我认为,如果没有将 size 的结构设置为2的幂,您将会看到性能损失。结构数组的性能问题通常是由于对齐

对齐与效果

为了最小化访问标量变量所需的指令数,变量必须存在于内存中其大小的多个字节的位置。结构的含义如下:

  1. 实际上,由于struct的地址等于其第一个成员的地址,因此给定struct的起始地址必须是其第一个成员大小的倍数,以字节为单位
  2. 对于编译器编写者,实用方法是将结构与其包含的最宽标量值的倍数对齐
  3. 结构数组在它们之间分配了填充,以保证这些对齐保证保持整个数组 - 大多数编译器将为您执行此操作! :)
  4. 还在结构中的变量之间添加填充,如果需要,以确保所有结构成员都正确对齐
  5. 处理结构对齐

    现代系统上的大多数编译器会自动在结构后添加填充,以满足自对齐类型的对齐要求。

    因此,通常,您的结构将与结构中最大元素的倍数对齐。作为结构中的long的结果,数组中的每个结构将间隔开,使得每个结构的起始地址是sizeof(long)的倍数。这是通过透明地在结构的末尾添加“slop”来实现的。试试这个,看看你得到了什么:

    #include <stdio.h>
    
    struct my_struct
    {
        long l1;
        long l2;
        long l3;
        long l4;
        long l5;
        long l6;
        long l7;
        char c;
    };
    
    int main( int argc, char** argv )
    {
        printf("sizeof(my_struct) == %lu\n", sizeof(struct my_struct));
        return 0;
    };
    
    /* EOF */
    

    关于包装的说明:

    通常,对于支持它们的系统上的自对齐类型,您可以通常使用__attribute__((packed)),但这可能会导致性能损失访问给定成员所需的机器指令数量将会增加。

    如果真的关心不会因为对齐斜率而浪费空间,并且您不需要其中一个长片的全部值,请查看是否可以移动char使用掩码进入其中一个长片或尝试使用位域。

    我个人最喜欢的结构包装和对齐资源之一:The Lost Art of C Structure Packing

答案 1 :(得分:0)

  

是否会将填充自动添加到结构中进行优化   内存,或者我应该在结构中添加一些内容来实现它   更接近2位的功率,以优化处理   那些结构的数组?

不,您不需要在struct声明中添加任何内容。一般来说,编译器会处理对齐和填充。 您可以通过打印sizeof(your_struct);的输出来自行测试。

然而,可以做相反的事情并优化尺寸而不是速度。这可能很有用,因为内存是恐慌,或者如果您通过网络发送原始结构。海湾合作委员会有__attribute__((packed))来做这件事。