__builtin_prefetch,它读了多少?

Mik*_*ail 16 c++ optimization gcc x86-64 numerical-methods

我正在尝试使用优化一些C++(RK4)

__builtin_prefetch
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚如何预取整个结构.

我不明白const void *addr读了多少.我想要下载fromto加载的值.

for (int i = from; i < to; i++)
{
    double kv = myLinks[i].kv;
    particle* from = con[i].Pfrom;
    particle* to = con[i].Pto;
    //Prefetch values at con[i++].Pfrom & con[i].Pto;
    double pos = to->px- from->px;
    double delta = from->r + to->r - pos;
    double k1 = axcel(kv, delta, from->mass) * dt; //axcel is an inlined function
    double k2 = axcel(kv, delta + 0.5 * k1, from->mass) * dt;
    double k3 = axcel(kv, delta + 0.5 * k2, from->mass) * dt;
    double k4 = axcel(kv, delta + k3, from->mass) * dt;
    #define likely(x)       __builtin_expect((x),1)
    if (likely(!from->bc))
    {
            from->x += (( k1 + 2 * k2 + 2 * k3 + k4) / 6);
    }
}
Run Code Online (Sandbox Code Playgroud)

链接:http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/

Bas*_*tch 22

我认为它只发出一个FETCH机器指令,它基本上取一个行缓存,其大小是特定于处理器的.

你可以使用__builtin_prefetch (con[i+3].Pfrom)例如.根据我的(小)经验,在这样的循环中,最好事先预取几个元素.

不要__builtin_prefetch经常使用(即不要将很多它们放在循环中).如果需要,可以测量性能增益,并使用GCC优化(至少-O2).如果你非常幸运,手动__builtin_prefetch可以将你的循环性能提高10%或20%(但它也可能会伤害它).

如果这样的循环对您至关重要,您可以考虑在使用OpenCL或CUDA的GPU上运行它(但这需要重新编码OpenCL或CUDA语言中的一些例程,并将它们调整到您的特定硬件).

还使用最近的GCC编译器(最新版本是4.6.2),因为它在这些领域取得了很大进展.


(2018年1月添加:)

硬件(处理器)和编译器在缓存方面都取得了很大进展,所以__builtin_prefetch今天使用它似乎没那么有用(2018年).一定要进行基准测试.

  • 是的:如果您打算这样做,请确保您在循环之前和之后对循环进行基准测试.你有可能让它变得更糟或没有区别. (7认同)
  • 谢谢你的帖子.我做了3个基准测试:没有优化= 100%,提前阅读[i + 3] 100%和[i + 10] 200%+.所有这些都是用-03和快速数学完成的 (5认同)

小智 13

它读取缓存行.缓存行大小可能会有所不同,但在现代CPU上最有可能是64字节.如果您需要读取多个缓存行,请查看prefetch_range.