__builtin_xxx指令学习【2】__builtin_prefetch

2023-05-16

__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,以便提高程序的执行效率。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

__builtin_xxx指令学习【2】__builtin_prefetch 的相关文章

  • linux vi指令学习

    内容 命令 作用 打开文件 vi文件名 vi 文件名 43 行号 退出 保存文件 w 保存文件 wq 保存文件并退出vi q 强制退出vi xff0c 即使该文件被修改 xff0c 也不保存该文件 进入编辑模式 i在光标前开始插入文本 a在
  • 列出 javascript 中所有内置函数?

    js 有没有办法列出所有内置函数及其参数列表上的一些信息 我真的找不到任何关于反射来做这类事情的东西 编辑 Math sin之类的函数其实就是我要列出的 实际上都是内置函数 也许是这样的 for var x in window if win
  • cuda 中预取(通过 C 代码)

    我正在通过 C 代码在 CUDA Fermi GPU 中进行数据预取 Cuda 参考手册讨论了 ptx 级别代码的预取 而不是 C 级别代码的预取 任何人都可以向我提供一些有关通过 cuda 代码 cu 文件 预取的文档或内容吗 任何帮助
  • 如何预取不常用的代码?

    我想将一些代码预取到指令缓存中 代码路径很少使用 但我需要它位于指令缓存中 或者至少在 L2 中 在极少数情况下 我对这些罕见的情况有一些提前通知 mm prefetch 对代码有用吗 有没有办法将这些不常用的代码放入缓存中 对于这个问题
  • 可能(x) 和 __builtin_expect((x),1)

    我知道内核使用likely and unlikely宏惊人 宏的文档位于内置函数 long builtin expect long exp long c 但他们并没有真正讨论细节 编译器到底是如何处理的likely x and builti
  • 装饰 Hex 函数以填充零

    我写了这个简单的函数 def padded hex i l given int i given len l hex result hex given int 2 remove 0x from beginning of str num hex
  • Java内置库的实现

    有谁知道 如果可能的话 我可以在哪里查看java内置库的代码 我试过了Ctrl Shift B 这是 Netbeans 与 Eclipse 的等价物Ctrl Shift T 到 转到源代码 但我只能看到方法头 而正文始终是 compiled
  • 为什么 django 的 prefetch_lated() 只能与 all() 一起使用,而不能与 filter() 一起使用?

    假设我有这个模型 class PhotoAlbum models Model title models CharField max length 128 author models CharField max length 128 clas
  • Python更改异常可打印输出,例如重载__builtins__

    我正在寻找一种方法将异常的可打印输出更改为愚蠢的消息 以便了解有关 python 内部结构的更多信息 并与朋友搞混 到目前为止没有成功 考虑下面的代码 try x is not defined except NameError as exc
  • 在bash中,如何获取set -x的当前状态?

    我想在我的脚本中临时设置 x 然后返回到原始状态 有没有办法在不启动新的子shell的情况下做到这一点 就像是 echo was on if echo was on then set x else set x fi 您可以检查的值 查看当前
  • 安装两个版本时如何判断我正在运行哪个版本的 R

    我的电脑上有两个R目录 one is home R 2 15 2 另一个是 home R 2 15 1 当我输入R 我可以启动R 现在我想知道哪个R正在运行 2 15 1还是2 15 2 2021 年 5 月 20 日更新 在 R 终端中
  • 使用 __builtin_expect 的指南

    我应该用 gcc 包装什么 builtin expected内的宏if具有多个嵌套测试 我有这个代码 if x
  • 如何在 PHP 中检测浏览器的预取?

    某些页面可以由浏览器预取 请参阅this http www whatwg org specs web apps current work multipage links html link type prefetch or that htt
  • 如何在tensorflow中使用自定义python函数预取数据

    我正在尝试预取训练数据以隐藏 I O 延迟 我想编写自定义 Python 代码来从磁盘加载数据并预处理数据 例如通过添加上下文窗口 换句话说 一个线程进行数据预处理 另一个线程进行训练 这在 TensorFlow 中可能吗 更新 我有一个基
  • 当 __builtin_memcpy 替换为 libc 的 memcpy 时

    有一个C99 posix版本memcpy海湾合作委员会的功能 builtin memcpy 有时它可以被 GCC 替换为 memcpy 的内联版本 而在其他情况下它可以通过调用 libc 的 memcpy 来替换 例如 有人指出here h
  • 预取指令是否需要在退出之前返回结果?

    在最新的 Intel 和 AMD CPU 上 已执行但请求的行尚未到达指定缓存级别的预取指令是否仍会退出 也就是说 预取的退休是 阻塞 的 因为它看起来对于加载来说是 阻塞 的 还是非阻塞的 关于英特尔处理器 没有 Intel优化手册第7
  • 为什么我可以从“eval”调用“print”

    对于代码 usr bin python src print import os obj compile src exec eval obj builtins False 我得到输出 Traceback most recent call la
  • 以编程方式禁用 AMD 系统上的硬件预取

    有没有一种方法可以像在 Intel 系统中那样以编程方式禁用 AMD 系统上的硬件预取器 如这个话题 https stackoverflow com questions 784041 how do i programatically dis
  • 与内置函数的命名冲突[重复]

    这个问题在这里已经有答案了 我犯了一个错误 如下所示 gt gt gt list a b c 但现在我想使用内置函数list 可以看到 listname之间存在命名冲突list和内置函数list 我该如何使用list作为内置函数而不是变量而
  • 预取双类成员需要转换为 char*?

    我有一个正在使用的课程 mm prefetch 预先请求包含 double 类型的类成员的缓存行 class MyClass double getDouble return dbl other members double dbl othe

随机推荐

  • 用C语言实现卷积操作(包含单通道单卷积和多通道多卷积以及维度的转换)

    用C语言实现卷积 单通单卷积多通道多卷积维度转换 xff08 多维转一维 xff09 完整代码实现 xff1a 单通单卷积 卷积其实就是个点成相加的过程 原理图如下 xff1a 关键代码实现 xff1a span class token c
  • 基于深度学习的车牌识别项目的APP部分之图像预处理(一):C语言读取bmp图像信息

    车牌识别项目之图像预处理一 xff1a C语言读取bmp图像信息 一 什么是bmp文件二 BMP格式结构1 文件信息头2 图像描述信息块3 BMP调色板4 BMP图像数据区 像素存储 像素数据 位图像素格式 三 原理实现 xff1a 1 打
  • 基于深度学习的车牌识别项目的APP部分之图像预处理(二):C语言实现bmp的二值化处理

    基于深度学习的车牌识别项目的APP部分之图像预处理 xff08 二 xff09 xff1a C语言实现bmp的二值化处理 一 二值化概念二 代码实现三 运行结果 xff1a 1 图像是8位深度的运行结果 xff1a 2 图像是16位深度的运
  • rviz和tf树报错修改

    跟着这个博主进行多机器人仿真 xff0c 一直出错 xff0c 有点崩溃了 ROS仿真笔记之 基于gazebo的ROS多机器人仿真 gwpscut的博客 CSDN博客 TF REPEATED DATA warnings ROS Answer
  • 港科大GVINS编译与运行教程

    GVINS GVINS是香港科技大学沈劭劼团队开源的基于因子图优化的GNSS 视觉 惯导紧耦合多传感器组合导航软件 GVINS是一个基于非线性优化的系统 xff0c 它将 GNSS 原始测量与视觉和惯性信息紧密融合 xff0c 以实现实时和
  • 硬件结构——(6) 软中断

    1 中断是什么 xff1f 在计算机中 xff0c 中断是 系统用来响应硬件设备请求 的一种机制 操作系统收到 硬件的中断请求后 xff0c 会打断正在执行的进程 xff0c 然后调用内核中的 中断处理程序 来响应请求 中断是 种 异步的事
  • C++将类序列化和反序列化到共享内存

    这里用模板泛化一下 template lt typename T gt int saveToShm const T amp obj key t key 61 gen shm key int shmId 61 shmget key sizeo
  • C++使用rapidjson进行类的序列化与反序列化

    目录 序列化 amp 反序列化单个对象序列化反序列化使用示例 序列化 amp 反序列化对象列表 C 43 43 中可以使用第三方库来实现将类序列化成JSON文件 xff0c 以及读取JSON文件内容反序列化为类对象 这里使用rapidJso
  • c++用vector实现定长队列

    目录 queue实现vector实现 我们可以用queue或vector实现定长队列 xff0c 但是如果我们有遍历定长队列的需求的话 xff0c 使用queue不是一个好的选择 xff0c 因为queue本身不支持直接访问元素 queue
  • c++判断文件是否存在

    可以使用C 43 43 的文件流来判断文件是否存在 以下是一个简单的函数 xff0c 可以通过文件名判断文件是否存在 xff1a span class token macro property span class token direct
  • 相机内外参数的意义

    1 内参数 xff1a 由于相机坐标系使用的是毫米制的单位 xff0c 而图像平面使用的像素为单位 内参数的作用就是在这两个坐标系之间进行线性的变化 相机光轴中心Z轴方向与像平面交点称为投影中心 xff0c 其坐标为 xff0c 其单位为像
  • C++实现读写分离的双缓冲buffer

    目录 1 双缓冲区 读写分离2 后台线程定时更新数据3 类设计完整代码cache cppcache hmain cppmakefile 读写分离的双缓冲buffer有以下好处 xff1a 提高了并发读写的效率 xff1a 在多线程环境下 x
  • 返回引用与返回值与返回std::move(obj)

    返回引用与返回值相比 返回引用与返回值相比有以下几个好处 xff1a 减少内存开销 xff1a 返回值需要在函数内部创建一个临时对象 xff0c 然后将该对象的副本返回给调用者 这个过程需要分配内存 复制数据等操作 xff0c 会增加内存开
  • error: non-member function ‘XXX::IsValid(const T&)’ cannot have cv-qualifier

    这个错误提示表明你定义的函数 IsValid 是一个非成员函数 xff0c 并且带有 const 限定符 在 C 43 43 中 xff0c 非成员函数不能带有 const 限定符 xff0c 因为它们没有隐式的 this 指针 xff0c
  • c++使用regex报错regex_error

    原本写了个同时识别IPv4和IPv6地址的C 43 43 函数 xff1a span class token macro property span class token directive hash span span class to
  • c++实现日志类(写入logfile)

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • c++中以类对象作为key用于unordered_map、map,以及std::tie技巧使用

    我有一个类 span class token keyword class span span class token class name UserRegion span span class token punctuation span
  • std::set_difference用法

    std set difference 是 C 43 43 STL 中的一个算法 xff0c 用于计算两个有序范围之间的差集 xff0c 并将结果存储到另一个有序范围中 std set difference 的函数签名如下 xff1a spa
  • __builtin_xxx指令学习【1】__builtin_expect

    builtin expect是GCC编译器提供的一个内置函数 xff0c 用于告诉编译器一个分支的执行概率 xff0c 以便编译器在生成机器码时进行优化 它的语法如下 xff1a span class token function buil
  • __builtin_xxx指令学习【2】__builtin_prefetch

    builtin prefetch是GCC编译器提供的一个内置函数 xff0c 用于预取数据到CPU的缓存中 xff0c 以便提高程序的执行效率 它的语法如下 xff1a builtin prefetch const void addr in