繁体   English   中英

如何设计性能对象

[英]How to design objects for performance

在最近读一关于物理引擎开发的书时 ,我遇到了一个我以前从未考虑过的设计决策。 这与CPU处理内存中的原始字节的方式有关。

考虑以下课程:

class Foo
{
    public:
        float x;
        float y;
        float z;

        /* Constructors and Methods */

    private:
        float padding;
}

作者声称填充,在x86架构中将对象的大小增加到四字,可以显着提高性能。 这是因为4个单词在内存中比3更干净 ,这是什么意思? 用冗余数据填充对象以提高性能对我来说似乎很矛盾。

这也引出了另一个问题,那些大小为1或2个单词的对象呢? 如果我的班级是这样的:

class Bar
{
    public:
        float x;
        float y;

        /* Constructors and Methods */

    private:
        /* padding ?? */
}

我应该在这个类中添加填充,以便它在内存中更干净地放置吗?

编译器有责任决定合理的填充(假设是典型的访问模式)。 编译器确实比你想象的更了解你的机器。 此外,你的机器将与你在一起几年; 该计划将持续数十年,在各种平台上运行,受到令人难以置信的各种使用模式的影响。 对于今天的i7来说,最好的是明天的i8或ARMv11。

为追求难以捉摸的“性能”而混淆的代码完全属于过早优化 永远记住你的时间(写作,测试,调试,一周后再次理解,调整代码)比可能浪费的计算机时间要贵得多(除非所说的代码每天在数百万台机器上运行数千次) , 那是)。 代码调整完全没有任何意义,直到你有足够的事实表明性能不够, 测量结果告诉你,改变这种结构是一个值得担心的瓶颈。

处理器并不像人类那样逐字节地“读取”存储器,它们按块处理块,可变大小取决于处理器。 它被称为内存访问粒度;

通过“内存对齐”您的对象,访问时间可能更快,您还可以避免数据碎片。

您可以在此处阅读有关数据对齐的更多信息

编辑:我不是说这是一个好的或坏的做法,只是分享我所知道的。

在回答这个问题时,有两个非常重要的事情要说。

首先,如果您要调整代码以获得性能优势,并且如果您认为值得(无论出于何种原因),您必须首先编写基准。 你必须能够尝试两者并衡量差异。

其次,这种调整将取决于汇编语言如何与硬件交互。 必须能够阅读汇编语言代码并理解不同的指令集和硬件访问模式,以便了解这些调整可能起作用的原因。

最后,你的问题没有孤立的答案。 这取决于这些对象是单独分配还是集合; 他们旁边是否还有其他物品; 以及编译器如何为每种情况生成代码。 在所有可能的情况下,二次幂边界上的对齐将比未对齐更快,但是适合高速缓存的集合比不这样做的集合更快。 我不希望填充8或4字节来提高性能,但如果它很重要,我会尝试并测试结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM