当前位置: 首页 > news >正文

C++深度优化——cacheline测试

cacheline是内存调度的基本结构,其大小一般为32B或者64B。关于本机具体的配置信息可以在配置文件中看到:

这里可以看到我的这台机器的cacheline大小是64B。对于cacheline在多核处理器中有一个伪共享的状态,具体可以参考以下博客:高速缓存伪共享 - 知乎(这个大佬写了1K多篇文章,我感觉需要好好消化消化。)

所谓“伪共享”实际上是主存中的一个cacheline中的内容,在同一时刻只能被多核中的一个捕获处理。

程序如下:

#include <unistd.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <string.h>
#include <thread>
#include <chrono>
#include <iostream>
#include <atomic>struct common
{volatile unsigned long a;volatile unsigned long b;
};
struct common_fulfill
{volatile unsigned long a;unsigned long az[7];volatile unsigned long b;unsigned long bz[7];
};using namespace std;
int main(int argc, char** argv)
{cout << "no-fulfill" << endl;do{common c;c.a = 0;c.b=0;volatile bool brun = true;thread t1([&c,&brun](){while(brun)c.a+=1;});thread t2([&c,&brun](){while(brun)c.b+=1;});std::this_thread::sleep_for(std::chrono::seconds(1));brun=false;//std::atomic_thread_fence(std::memory_order_seq_cst);t1.join();t2.join();cout << "a:" << c.a << "\t b:" << c.b << endl;}while(0);cout << "fulfill" << endl;do{common_fulfill c;c.a = 0;c.b=0;volatile bool brun = true;thread t1([&c,&brun](){while(brun)c.a+=1;});thread t2([&c,&brun](){while(brun)c.b+=1;});std::this_thread::sleep_for(std::chrono::seconds(1));brun=false;//std::atomic_thread_fence(std::memory_order_seq_cst);t1.join();t2.join();cout << "a:" << c.a << "\t b:" << c.b << endl;}while(0);cout << "add-per-second" << endl;do{common_fulfill c;c.a = 0;c.b=0;volatile bool brun = true;thread t1([&c,&brun](){while(brun)c.a+=1;});std::this_thread::sleep_for(std::chrono::seconds(1));brun=false;//std::atomic_thread_fence(std::memory_order_seq_cst);t1.join();cout << "a:" << c.a << endl;}while(0);return 0;
}

注意,我在struct c中的a和b都增加了volatile关键字,这个关键字的作用在于将缓存和主存硬绑定,有点同步打开文件描述符的意思。这样,可以预期到内存会被以cacheline为单位上锁。然后进行编译。

这里用的是O2进行优化,然后执行,结果如下:

这个地方可以发现,在没有填充的情况下,1秒内访问的速度是3.5*10^8;而将struct c填充到128字节的访问次数是4.9*10^8。几乎同样的代码,将最后的单CPU每秒能进行加法数量的统计去掉之后,结果如下:

可以看到,两次的情况,不填充的速度总是要远远逊色于填充的情况。我们在做服务器程序深度优化的时候,要注意这个硬件细节,有时候能够极大地加快程序的运行速度。可以注意到,伪共享状态只是影响了CPU的运行时间,服务器的大量CPU时间会在等待锁中消耗,所以现在无锁代码非常流行。另外为什么增加或者修改代码的大小就会影响CPU的执行效率呢?这个问题还是没有得到答案。

http://www.lryc.cn/news/167833.html

相关文章:

  • 【数字IC/FPGA】Verilog中的递归调用
  • 禁用Win10自动更新
  • 算法通关村-----动态规划高频问题
  • 记一起小意外事件引起的批量重命名文件名
  • 【Excel函数】Excel的Len函数求对象的字符数
  • 小白备战大厂算法笔试(八)——搜索
  • 〔022〕Stable Diffusion 之 生成视频 篇
  • 网络安全深入学习第三课——热门框架漏洞(RCE—Struts2远程代码执行)
  • 【uni-app】
  • Pytorch 多卡并行(3)—— 使用 DDP 加速 minGPT 训练
  • IAM、EIAM、CIAM、RAM、IDaaS 都是什么?
  • STM32 Cubemx 通用定时器 General-Purpose Timers同步
  • Ubuntu 20.04降级clang-format
  • 激活函数总结(三十四):激活函数补充(FReLU、CReLU)
  • 【LeetCode-简单题KMP】459. 重复的子字符串
  • Lua脚本
  • vue 封装一个Dialog组件
  • 外包干了2个月,技术退步明显。。。。。
  • python科研作图
  • 视锥体裁剪射线的算法
  • 程序员在线周刊(投稿篇)
  • uniapp——实现聊天室功能——技能提升
  • 脚本:用python实现五子棋
  • Java-华为真题-预定酒店
  • win10 自带虚拟机软件 虚拟CentOS系统
  • 【深度学习】 Python 和 NumPy 系列教程(十):NumPy详解:2、数组操作(索引和切片、形状操作、转置操作、拼接操作)
  • 3D视觉测量:复现Gocator的间隙面差
  • 文献综述怎么写?(以利用Zotero的文献管理软件为例)
  • 中尺度混凝土二维有限元求解——运行弯曲、运行光盘、运行比较、运行半圆形(Matlab代码实现)
  • Python文件存读取