17 optimization powerpc memcpy shark altivec
为了在PowerPC上寻找一个好的内存策略,我写了几个复制函数.使用具有高速缓存提示(dcb*)的Altivec或fp寄存器可以使大数据的简单字节复制循环的性能提高一倍.最初很满意的是,我定期记忆,看看它的比较...比我最好的速度快10倍!我无意重写memcpy,但我希望从中学习并加速几个简单的图像过滤器,这些过滤器花费大部分时间将像素移入和移出内存.
Shark分析显示它们的内部循环使用dcbt预取,有4个向量读取,然后是4个向量写入.在调整了我的最佳函数以便每次迭代运行64个字节之后,memcpy的性能优势仍然令人尴尬.我正在使用dcbz来释放带宽,Apple没有使用任何东西,但两个代码都倾向于对商店犹豫不决.
prefetch dcbt future dcbt distant future load stuff lvx image lvx image + 16 lvx image + 32 lvx image + 48 image += 64 prepare to store dcbz filtered dcbz filtered + 32 store stuff stvxl filtered stvxl filtered + 16 stvxl filtered + 32 stvxl filtered + 48 filtered += 64 repeat
有没有人对为什么非常相似的代码有如此戏剧性的性能差距有一些想法?我喜欢用真正的图像过滤器来腌制真正的图像过滤器!
附加信息:所有数据都是矢量对齐的.我正在制作图像的过滤副本,而不是替换原始图像.该代码在PowerPC G4,G5和Cell PPU上运行.Cell SPU版本已经非常快.
Shark分析显示它们的内部循环使用dcbt预取,有4个向量读取,然后是4个向量写入.调整我的最佳函数后,每次迭代也会运行64个字节
我可能会说明显而已,但由于你在问题中根本没有提到以下内容,因此可能值得指出:
我敢打赌,Apple选择的4个向量读取后跟4个向量写入与G5的流水线及其在"调度组"中对无序指令执行的管理有很大关系,因为它具有神奇的64字节完美线条大小.您是否注意到Nick Bastin的链接bcopy.s中的线路跳过?这意味着开发人员考虑了G5如何使用指令流.如果你想重现相同的性能,一次读取64字节数据是不够的,你必须确保你的指令组充分填充(基本上,我记得指令最多可以分为五个独立的指令组,前四个是非跳转指令,第五个只允许跳转.细节更复杂).
编辑:您可能也会对同一页面上的以下段落感兴趣:
根据G4和G3,dcbz指令仍然对齐32位字节的存储器段.但是,由于这不是G5上的完整缓存行,因此它不具备您可能希望的性能优势.有一个为G5新引入的dcbzl指令,它将一个完整的128字节高速缓存行归零.
可能是因为CPU缓存的原因。尝试运行CacheGrind:
Cachegrind 是一个缓存分析器。它对 CPU 中的 I1、D1 和 L2 缓存进行详细模拟,因此可以准确地查明代码中缓存未命中的来源。它可以识别每行源代码的缓存未命中、内存引用和执行指令的数量,以及每个函数、每个模块和整个程序的摘要。它对于用任何语言编写的程序都很有用。Cachegrind 运行程序的速度比正常情况慢约 20--100 倍。