我正在考虑大量的内存缓存优化,并希望得到一些反馈。考虑这个例子:
class example
{
float phase1;
float phaseInc;
float factor;
public:
void process(float* buffer,unsigned int iSamples)//<-high prio audio thread
{
for(unsigned int i = 0; i < iSamples; i++)// mostly iSamples is 32
{
phase1 += phaseInc;
float f1 = sinf(phase1);//<-sinf is just an example!
buffer[i] = f1*factor;
}
}
};优化理念:
void example::process(float* buffer,unsigned int iSamples)
{
float stackMemory[3];// should fit in L1
memcpy(stackMemory,&phase1,sizeof(float)*3);// get all memory at once
for(unsigned int i = 0; i < iSamples; i++)
{
stackMemory[0] += stackMemory[1];
float f1 = sinf(stackMemory[0]);
buffer[i] = f1*stackMemory[2];
}
memcpy(&phase1,stackMemory,sizeof(float)*1);// write back only changed mameory
}请注意,实际的样本循环将包含数千个操作。因此,stackMemory可以变得非常大。我认为它不会超过32kb (有没有更小的L1 ?)
堆栈内存中使用的变量的顺序重要吗?我希望不是,因为我想订购它们,这样我就可以减少写回大小。或者,L1缓存是否具有与内存相同的缓存行行为?
我有种预取的感觉,但我读到的所有关于预取的东西都是相对模糊的,关于如何有效地使用它。Try and error不是5000+代码行的选项。
代码可以在Win,Mac和iOS上运行。预计会出现任何ARM<->Intel问题?
有没有可能这种优化是无用的,因为所有的内存都是在循环的第一次迭代时被访问并传输到L1的?
感谢您的任何提示和想法。
发布于 2015-11-29 11:07:05
起初,我认为第二个类很可能会更慢,因为memcpy需要额外的内存访问和指令,而第一个类可以直接与这三个类成员一起工作,这三个类成员已经加载到寄存器中。
尽管如此,我还是尝试用-O2和-O3修改了GCC 5.2中的代码,结果发现,无论我怎么尝试,都得到了相同的汇编指令。考虑到memcpy通常必须做的所有额外的概念性工作,显然这些工作都被压得一干二净,这是相当令人惊讶的。
我能想到的一种情况是,在某些情况下,在某些编译器上,你的第二个版本可能会更快,那就是访问this->data_member所涉及的别名是否干扰了优化,并导致了对寄存器的冗余加载和存储。
在这种情况下,它与L1缓存无关,而与编译器端的寄存器分配有关。当你加载相同的内存(成员变量)时,缓存在很大程度上是不相关的,不管是连续的数据块,它完全与寄存器有关。尽管如此,我找不到任何一种情况可以导致这种情况发生,即编译器在一种情况下比另一种情况做得更差--我测试的每个情况都产生相同的结果。在一个足够复杂的现实世界案例中,可能会有所不同。
再说一次,在这种情况下,应该更安全地简单地这样做:
void process(float* buffer,unsigned int iSamples)
{
const float pi = phaseInc;
const float p1 = phase1;
const float fact = factor;
for(unsigned int i = 0; i < iSamples; i++)
{
phase1 += pi;
float f1 = sinf(p1);
buffer[i] = f1*fact;
}
}不需要使用memcpy将结果存储到一个数组中,然后再将其返回。这给优化器带来了额外的压力,即使在我的发现中,优化器设法消除了通常相关的开销。
我知道您的示例很简单,但是无论您处理多少数据成员,都没有必要将结构简化为这样一个原始数组(除非这样的数组实际上是最方便的表示)。从性能的角度来看,如果只使用局部变量而不是memcpy将数据成员聚合进和出到的数组,编译器将会有一个“更容易”的优化时间(即使现在的优化器非常神奇,并且可以处理这个问题)。
https://stackoverflow.com/questions/21350565
复制相似问题