首页 > 编程语言 >C++性能优化 —— __builtin_prefetch()

C++性能优化 —— __builtin_prefetch()

时间:2023-02-02 14:45:21浏览次数:105  
标签:__ cache C++ builtin 指令 prefetch data

C++性能优化 —— __builtin_prefetch()数据预读

References

  1. __builtin_prefetch()
  2. Prefetching with __builtin_prefetch
  3. Data Prefetch 数据预取

一、什么是 __builtin_prefetch()?

为了降低内存读取的cache-miss延迟,可以通过gcc提供的这个内置函数来预读数据。当知道数据的内存地址即将要被读取(在下一个load & store指令到来之前),在数据被处理之前,就可以在代码中通过指令通知目标,去读取数据并放到缓存中。

Note that the prefetching instruction is a hint, which means that your target processor might, or might not, actually prefetch the data.

二、用法

__builtin_prefetch (const void *addr[, rw[, locality]]) 

1. addr (required): 代表内存地址

  • 0 (default): prepare the prefetch for a read

  • 1 : prepare the prefetch for a write to the memory

2. rw (optional) : 编译时的常量

  • 0: None, the data can be removed from the cache after the access.

  • 1: Low, L3 cache, leave the data in the L3 cache level after the access.

  • 2: Moderate, L2 cache, leave the data in L2 and L3 cache levels after the access.

  • 3 (default): High, L1 cache, leave the data in the L1, L2, and L3 cache levels after the access.

三、适用场景

https://zhuanlan.zhihu.com/p/299596490

  1. prefetch最佳的引用场景是loop循环,因为loop循环中cache miss的概率非常大,我们可以用一个简单的loop来说明如何使用prefetch指令。

  • 图a,表示没有prefetch指令的循环体。
  • 图b,表示在每次循环体中,都首先预取下一次循环中需要的数据也就是第i+1个数据。
  • 图c,假设一个cache line的长度是4个字长,数组中每个元素的大小是一个字长,那么没必要每次都prefetch,因为prefetch本身是有开销的,应该尽量减小它本身带来的开销。所以应该每次prefetch后面4个元素。
  • 图d,在图c的基础之上,进一步在循环体之前先预取第0个元素,避免compulsory cache miss,然后在循环末尾再单独处理一下剩下几个元素。
  1. 大部分的prefetch策略应用场景都是基于数值运算和连续内存访问的程序,这些程序的内存模型更加容易预测,并且有着不是很高的cache利用率,这种程序中使用prefetch容易得到较大的性能提升。

四、缺点

  1. prefetch指令本身是有开销的,因为cpu需要存储prefetch指令的目标地址,通常是存在寄存器,这样一来就占用了cpu可用的寄存器空间,如果prefetch指令过多的话还会导致额外的主存访问带来更大的开销.

  2. prefetch除了本身的开销之外,还有可能带来cache pollution,如果被prefetch指令换入的cache line有可能在匹配的 load & store指令到来之前,又被换出了cache,这样不仅浪费了一次prefetch,还导致了cache miss。

标签:__,cache,C++,builtin,指令,prefetch,data
From: https://www.cnblogs.com/qiangz/p/17085951.html

相关文章

  • Advent of Code 2015: Day 9
    JP'sBlogGitHub*Flickr*ResumeProgrammingReviewsPhotographyMakerWritingResearchRSSAdventofCode:Day9https://blog.jverkamp.com/2015/1......
  • mysql查询优化工具
    本文转载自https://www.cnblogs.com/yidengjiagou/p/16594161.html optimizertraceoptimizertrace 可以帮助我们查看优化器生成执行计划的整个过程,以及做出的各种决......
  • 模板字符串
    ``新旧两版对比document.write('模板拼接'+zzz+'模板拼接')  document.write(`模板拼接${zzz}模板拼接`) 实例:letage=18document.write(......
  • 专升本倒计时60天学习记录
    倒计时学习情况60天上午:学习了高数,下午:学习了英语,晚上:做英语习题59天上午:没学,下午:高数,晚上:英语......
  • thymeleaf其他的内置工具(共16种)
    thymeleaf其他的内置工具(共16种)ExecutionInfo:获取页面模板的处理信息Messages:在变量表达式中获取外部消息的方法,与使用#{...}语法获取的方法相同URIs/URLs:转义部分UR......
  • Dubbo 入门系列之基于 Dubbo API 开发微服务应用
    目标从零上手开发基于Dubbo的微服务难度低环境要求系统:Windows、Linux、MacOSJDK8及以上(推荐使用JDK17)GitIntelliJIDEA(可选)Docker(可选)动手实......
  • CentOS7删除swap分区方法[转]
    转自:https://blog.csdn.net/micjlxx/article/details/121715217 删除swap分区方法1、删除逻辑卷上的swap分区同样还是先禁用swap#swapoff-v/dev/mapper/swap删除逻辑......
  • libevent 信号事件实现方式
    学会使用libevent,才能真正的掌握其是实现原理,我们先从一个简短的测试用例开始:1#include<sys/types.h>2#include<sys/stat.h>3#include<sys/queue.h>4......
  • 微星MSI GS65 9SE 电脑 Hackintosh 黑苹果efi引导文件
    硬件型号驱动情况主板处理器i79750h已驱动内存Micron 8ATF1G64HZ-3G2J116GB已驱动硬盘三星pm981(已更换sm961,并添加一块东芝512ssd用于安装win10)已驱动显卡Intel UHD......
  • (笔记)ntpd与ntpdate的区别
     一、ntp和ntpdate区别①两个服务都是centos自带的(centos7中不自带ntp)。ntp的安装包名是ntp;ntpdate的安装包是ntpdate。他们并非由一个安装包提供。②ntp守护进程为ntpd,......