__builtin_xxx指令学习【2】__builtin_prefetch

__builtin_prefetch是GCC编译器提供的一个内置函数,用于预取数据到CPU的缓存中,以便提高程序的执行效率。它的语法如下:

__builtin_prefetch (const void *addr, int rw, int locality)

其中,addr是一个指向要预取数据的地址的指针,rw是一个表示读写属性的整数,locality是一个表示预取数据的局部性的整数。__builtin_prefetch的返回值是void类型,它只是告诉CPU预取数据到缓存中,而不会等待数据被加载到缓存中。

__builtin_prefetch的使用背景是,现代CPU的缓存系统可以预取数据到缓存中,以便提高程序的执行效率。但是,如果预取的数据与程序的执行流程不符,就会导致CPU的缓存被清空,从而降低程序的执行效率。因此,为了让CPU的缓存预取机制更加准确,我们可以使用__builtin_prefetch来告诉CPU要预取哪些数据,从而让CPU的缓存预取机制更加准确。

__builtin_prefetch的内部原理是,它会向CPU发送一个预取数据的请求,然后CPU会将请求加入到预取队列中。当CPU空闲时,它会从预取队列中取出请求,并将请求的数据预取到缓存中。

每次抓多少是有具体的CPU实现决定的,但是至少会抓32字节。

下面是一个demo,在求和前,先预取下一部分数据。

需要注意的是访问数组p的当前元素时,CPU已经开始预取下一个元素的数据,所以不要使用p[i+1]。另外,预取的数据的距离也应该根据程序的执行流程和数据访问模式来选择。如果预取的数据距离当前元素太远或者太近,都会导致程序的执行效率降低。在这个示例代码中,我们使用了p[i + 100]来预取下一个元素的地址,100是一个经验值,可以根据具体情况进行调整。

#include <iostream>
#include <chrono>

int main() {
    int* p = new int[100000000];
    for (int i = 0; i < 100000000; ++i) {
        p[i] = i;
    }
    auto start = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < 100000000; ++i) {
        __builtin_prefetch(&p[i + 100]);
        p[i] += 1;
    }
    auto end = std::chrono::high_resolution_clock::now();
    std::cout << "Time: " << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << "ms\n";
    delete[] p;
    return 0;
}
[hanhandi@VM-33-162-centos ~/hanhan_CppScripts/test]$ ./test 
Time: 224ms
[hanhandi@VM-33-162-centos ~/hanhan_CppScripts/test]$ ./test 
Time: 217ms
[hanhandi@VM-33-162-centos ~/hanhan_CppScripts/test]$ ./test 
Time: 234ms
[hanhandi@VM-33-162-centos ~/hanhan_CppScripts/test]$ ./test 
Time: 233ms
[hanhandi@VM-33-162-centos ~/hanhan_CppScripts/test]$ ./test 
Time: 238ms
[hanhandi@VM-33-162-centos ~/hanhan_CppScripts/test]$ ./test 
Time: 216ms

如果不使用__builtin_prefetch,耗时如下,提升效果还是挺明显的

[hanhandi@VM-33-162-centos ~/hanhan_CppScripts/test]$ ./test 
Time: 269ms
[hanhandi@VM-33-162-centos ~/hanhan_CppScripts/test]$ ./test 
Time: 302ms
[hanhandi@VM-33-162-centos ~/hanhan_CppScripts/test]$ ./test 
Time: 309ms
[hanhandi@VM-33-162-centos ~/hanhan_CppScripts/test]$ ./test 
Time: 251ms
[hanhandi@VM-33-162-centos ~/hanhan_CppScripts/test]$ ./test 
Time: 244ms
[hanhandi@VM-33-162-centos ~/hanhan_CppScripts/test]$ ./test 
Time: 270ms

需要注意的是:

如果预取的数据与程序的执行流程不符,就会导致CPU的缓存被清空,从而降低程序的执行效率。

此外,如果预取的数据过多,就会导致CPU的缓存被占满,从而降低程序的执行效率。

如果编译器已经对程序进行了优化,那么使用__builtin_prefetch指令可能会导致程序的执行效率降低。

因此,需要根据程序的执行流程和数据访问模式来合理使用__builtin_prefetch,以便提高程序的执行效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拾牙慧者

欢迎请作者喝奶茶

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值