我正在阅读以下文章,
What Every Programmer Should Know About Compiler Optimizations
目前还有其他一些重要的优化措施 任何编译器的功能 - 例如,替换低效率 具有高效算法的算法,或改变数据的布局 改善地方的结构。
这是否意味着如果我更改类中数据成员的序列( layout ),它会影响性能吗?
所以,
class One
{
int data0;
abstract-data-type data1;
};
性能差异,
class One
{
abstract-data-type data0;
int data1;
};
如果这是真的,那么在定义类或数据结构时,经验法则是什么?
答案 0 :(得分:2)
位置主要是针对缓存位置。编写数据结构和算法以主要从缓存中运行使得算法尽可能快地运行。缓存局部性是快速排序快速的原因之一。
对于数据结构,您希望保持数据结构中彼此相对接近的部分彼此相对接近,以避免刷新有用的缓存行。
此外,您可以重新排列数据结构,以便编译器将使用占用所有成员所需的最少内存量,并仍然可以有效地访问它们。这有助于确保您的数据结构消耗最少数量的缓存行。
当前x86-64架构(核心i7)上的单个缓存行为64字节。
答案 1 :(得分:1)
我不是数据/结构局部性方面的专家,但它与你如何组织数据有关,以避免CPU缓存来自整个CPU的内存位,从而通过不断等待内存提取来减慢程序速度
例如,链接列表可能遍布整个内存。但是,如果您将其更改为一系列"元素"然后它们都处于连续的内存中 - 如果你需要一次遍历所有数组(这只是一个例子),这将节省内存访问时间
<强>此外:强> 同样考虑到一些STL库,我不是100%确定哪些是最好的,但其中一些(例如列表)在地方方面相当糟糕。 另一个可能更常见的例子是指针数组,其中指向的元素可以分散在内存中。 当然,你不能总是轻易避免这种情况,因为你有时需要能够动态添加/移动/插入/删除元素......
<强>要点:强> 它基本上意味着要注意如何在内存访问方面布局数据。
答案 2 :(得分:0)
按照您访问它们的频率对班级成员进行排序。这最大化了热度&#34;包含类头部的缓存行,增加了它保持缓存的可能性。您关心的另一个因素是打包 - 由于对齐,重新排列成员声明的顺序可能会导致类的大小减小,从而降低缓存压力。
(当然,这些都不是确定的。这些经验法则不能替代分析。)