一、什么是预取

预取是指将内存中的指令和数据提前存放到cache(L1、L2、L3)中,从而加快处理器执行速度。

Cache预取可以通过硬件或者软件实现,也就是分为硬件预取和软件预取两类。

  • 硬件预取,是通过处理器中专门的硬件来实现的,该硬件监控正在执行程序中请求的指令或数据,识别下一个程序需要的流然后预取到处理器中。
  • 软件预取,是通过编译器分析代码然后在程序编译的过程中插入prefetch。这样在执行过程中在指定位置就会进行预取的动作。

本文讨论的预取指软件预取。

二、使用_mm_prefetch预取

win10下,vs2017直接#include <Windows.h>就可以使用此函数了。

函数原型如下:

void _mm_prefetch(char const *p, int sel);

从地址p处预取大小为cache line的一块数据至缓存。

参数sel指示预取方式:

  • _MM_HINT_T0,预取数据到所有缓存
  • _MM_HINT_T1,预取到L2,L3缓存,但是不到L1缓存
  • _MM_HINT_T2,仅预取数据到L3缓存
  • _MM_HINT_NTA,预取数据到非临时缓冲结构中,可以最小化对缓存的污染。

如果在CPU操作数据之前,我们就已经将数据主动加载到缓存中,那么就减少了由于缓存不命中,需要从内存取数的情况,这样就可以加速操作,获得性能上提升。使用主动缓存技术来优化内存拷贝。

我们编写一段测试代码,用来测试数据预取与不预取2种情况下的区别。

prefetchTest.cpp

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <Windows.h>
#include <emmintrin.h>#define INT_COUNT        (5*1024*1024)inline int calculate(int input)
{int val = (input % 99) * (input / 98);val = val ? val : 1;double n = sqrt(sqrt((double)(unsigned)input * 1.3));double m = sqrt(sqrt((double)(unsigned)val * 0.9));return (int)((double)input * (double)val * m / (n ? n : 1.1));
}int run_withprefetch(const int *array, int size, int step, int prefetch)
{int result = 0;printf("run with prefetch(%d)...\n", prefetch);for (int i = 0; i < step; i++) {for (int j = i; j < size; j += step) {int k = j + step * prefetch;if (k < size) {_mm_prefetch((char*)&array[k], _MM_HINT_T0);
//              _mm_clflush(&array[k]);}result += calculate(array[j]);}}return result;
}int run(const int *array, int size, int step)
{int result = 0;printf("run...\n");for (int i = 0; i < step; i++) {for (int j = i; j < size; j += step) {result += calculate(array[j]);}}return result;
}int main()
{int select;scanf("%d", &select);int* array = new int[INT_COUNT];for (int i = 0; i < INT_COUNT; i++){array[i] = i;}long t1 = GetTickCount();int result;if (select == 0){result = run(array, INT_COUNT, 1024);}else{result = run_withprefetch(array, INT_COUNT, 1024, 1);}long t2 = GetTickCount();std::cout << (t2 - t1) << "ms" << std::endl;std::cout << "result:" << result << std::endl;delete[] array;
}

编译执行,输入0表示执行不预取的计算逻辑,输出结果如下:

可以看到计算完毕消耗687ms。

重新执行,输入1表示执行预取计算逻辑,输出结果如下:

可以看到计算完毕消耗391ms,性能得到大幅提升。这就是数据预取的威力。

三、使用_mm_clflush清除cache line

win10下,vs2017直接#include <emmintrin.h>就可以使用此函数了。

函数原型如下:

void _mm_clflush(void const* p);

此函数可以手动清除p地址处cache line缓存(清除大小为line size)。

我们打开prefetchTest.cpp中“_mm_clflush(&array[k]);”代码的注释。
这样的话,就是先预取数据,然后立马反悔,清除cache line缓存,相当于是没有预取。

编译执行,输入1,输出结果如下:

可以看到计算完毕消耗937ms。相比于不预取时的687ms,反而更加耗时了,可能是因为手动清除cache line比较影响性能吧。

四、总结

注 意,CPU对数据操作拥有绝对自由!使用预取指令只是按我们自己的想法对CPU的数据操作进行补充,有可能CPU当前并不需要我们加载到缓存的数据,这样,我们的预取指令可能会带来相反的结果,比如对于多任务系统,有可能我们冲掉了有用的缓存。不过,在多任务系统上,由于线程或进程的切换所花费的时间相对于预取操作来说太长了,所以可以忽略线程或进程切换对缓存预取的影响。

另外,数据预取只对那些内存读取是它瓶颈的程序才能起到很好的优化,毕竟只是加快了内存访问速度而已。那些对内存性能要求不高,对计算复杂度较高的程序,可能效果就不会那么明显。还有一些计算复杂度和内存性能要求都不高的程序,预取与不预取可能效果也不明显。

参考链接:

《CPU预取与性能简介》

《memory prefetch浅析》

《Intel 平台编程总结----缓存优化之数据预取》

《SSE中使用_mm_prefetch加速计算》

《clflush通过C函数使缓存行无效》


若对你有帮助,欢迎点赞、收藏、评论,你的支持就是我的最大动力!!!

同时,阿超为大家准备了丰富的学习资料,欢迎关注公众号“超哥学编程”,即可领取。

本文涉及工程代码,公众号回复:11PrefetchAndClflushTest,即可下载。

CPU数据预取对软件性能的影响相关推荐

  1. RecyclerView 数据预取

    本文讲的是RecyclerView 数据预取, 更快处理任务,使滚动和滑动更流畅 在我小时候,妈妈为了治疗我的拖延症,总是告诉我:"如果你现在打扫你的房间,就不用以后再打扫了."但 ...

  2. Oracle中用system存数据,【学习笔记】Oracle表空间 数据存放system表空间影响数据库性能...

    天萃荷净 分享一篇,关于Oracle数据库system表空间研究,不能将用户数据存放在system表空间的原因 为什么不建议客户把业务数据存放到SYSTEM表空间中,一直想通过试验的数据来说明问题,今 ...

  3. ssd测试软件和实际 速度,测出真相!实测CPU/内存对SSD性能的影响

    1解析CPU,内存和硬盘三者关系 [PConline 评测]不同于传统的机械硬盘,固态硬盘的组成很"简单",主控+闪存+PCB+外壳(缓存有些SSD直接省去).那实际影响SSD性能 ...

  4. 【Java 并发编程】线程简介 ( 并发类型 | 线程状态 | CPU 数据缓存 )

    文章目录 一.并发类型 二.线程状态 三.CPU 数据缓存 一.并发类型 并发类型 : Thread Runnable Future ThreadPool 其中 Runnable , ThreadPo ...

  5. 内蒙古电力交易对数据中心用电费用的影响分析

    内蒙古电力交易对数据中心用电费用的影响分析 从北京往西北方向出发,沿着京藏高速驱车约5个小时,经过张家口,即可到达中国的"草原云谷"-内蒙古自治区乌兰察布市.凭借着优越的地理位置, ...

  6. 特殊时期,对数据中心运营有哪些影响?

    武汉疫情还没有结束,很多企业已经开工或是线上办公了.这次疫情对很多行业影响不小,特别是餐饮等行业受到了不小的打击,那么对数据中心行业有哪些影响呢? 昨天小编做了一个小调研基本有这么几点: 1.故障处理 ...

  7. cpu高对计算机有什么影响吗,CPU损坏对电脑造成哪些影响

    cpu损坏会直接对电脑造成很大的影响的.学习啦小编为大家收集整理了cpu损坏对电脑造成的影响,供大家学习借鉴参考,希望对你有帮助! CPU损坏会导致电脑出现哪些故障 当电脑出现运行不稳定.通电后不能启 ...

  8. 大数据对社交媒体的影响_数据如何影响媒体,广告和娱乐职业

    大数据对社交媒体的影响 In advance of our upcoming event - Data Science Salon: Applying AI and ML to Media, Adve ...

  9. 医疗保健、零售、金融、制造业……一文带你看懂大数据对工业领域的影响!...

    作者 | Zubair Hassan 译者 | 风车云马 责编 | 徐威龙 封图| CSDN 下载于视觉中国 随着大数据技术的兴起,工业领域在很大程度上发生了变化.智能手机和其他通讯方式的使用迅速增加 ...

最新文章

  1. javascript中构造函数的返回值问题和new对象的过程
  2. NOIP2002 均分纸牌
  3. [ Nowcoder Contest 165 #D ] 合法括号序列
  4. CSS3 transform
  5. 数据结构c语言版第16页,数据结构c语言版
  6. 使用OpenCV3处理图像
  7. 连载17:软件体系设计新方向:数学抽象、设计模式、系统架构与方案设计(简化版)(袁晓河著)...
  8. vs 2005 多語言
  9. Atitit 得到mybatis 实际 sql 1.1. 使用mybatis工具提供的,只能出现问号一大堆不行 1 1.2. 配置log 打印sql依然不行,里面有问号。。 4 1.3. 配置p
  10. ORACLE有EXCEL中trend函数,借助Excel TREND 函数来解决线性插值的计算
  11. 怎样搬运视频不侵权,王者剪辑的指纹检测如何检测原创度
  12. iOS逆向之微信和支付宝修改步数 简洁无脑版
  13. 铁三角- 倒数348天
  14. Backordered even the inventory is sufficient在库存量满足的情况下PICK却BACKORDER
  15. 您需要计算机管理员权限,计算机中出现“你需要计算机管理员提供的权限才能对此文件进行更改”错误的解决方法...
  16. Vijos P1197 费解的开关
  17. 前端基础学习-element-ui表格表头做成斜线表头
  18. canvas-樱花飘落
  19. offline translator android app,PROMT Offline Translator English Pack
  20. 使用C/C++的#include命令(文件包含命令)时,文件名用尖括号或双撇号(双引号)括起来的区别

热门文章

  1. 31岁拿下阿里p7的offer,朋友都表示不屑,你怎么看?
  2. IPhone8 升级变砖复活记
  3. 计算机博士要学数学吗,科学网—计算机博士与数学 - 马飞的博文
  4. 国产化适配之人大金仓数据库(一)安装启动测试
  5. python循环发送短信验证码_python发送短信验证码
  6. C语言中的stdbool.h头文件
  7. 从0开始在家使用云GPU服务器
  8. C语言转VB6,如何从c语言查询vb6 ide的模式#
  9. Windows运行(快捷键Win+R)命令大全 及 快捷键
  10. 什么是大数据?大数据能为我们带来什么?