杂七杂八系列----C#代码如何影响CPU缓存速度?
CPU与RAM的隔阂
CPU与RAM是两个独立的硬件,并非集成在一起。所以他们两个之间一定会存在一个连接的桥梁
,这个桥梁的名字叫做内存总线。
内存总线由三部分组成:
地址总线(Address Bus)
用于传输内存地址,也就是我们经常看到的0X77F84FAB这种类似的内存地址,一根总线代表一个电信号,一个电信号能传递高电平/低电平
两种信息,用二进制表示就是1/0。因此总线数量的多少决定了可以传递内存地址的大小,比如你有32根总线,就代表你总线宽度32。2^32=4294967296,等于4GB内存,这就是32位操作系统只支持4G内存的由来。数据总线(Data Bus)
用于传输数据,原理同上,一根总线代表1bit传输段位,64根总线就是 64bit=8byte。一次性可以传输8byte单位的数据。控制总线(Control Bus)
用户传输控制信号,比如一根用来"读信号输出"的开关,一根"写信号输出"的开关。一根"时钟信号"的开关
CPU Cache
可以看到,假设CPU要读取1kb的数据,你的数据总线总线只有64根,1024/8=128,你需要来回倒腾128次,才能读取完毕,这一来二去就加大了内存之间的延迟,为了优化此性能瓶颈,CPU除了寄存器外临时存储数据,还内置了Cache来临时存储数据与指令。
特性 | L1缓存 | L2缓存 | L3缓存 |
---|---|---|---|
速度 | 1-2纳秒 | 约10纳秒 | 约30纳秒 |
容量 | 几十KB到几百KB | 几百KB到几MB | 几MB到几十MB |
位置 | 集成在 CPU 核心内部 | 每个核心独立拥有(位于核心附近) | 多核共享(位于 CPU 芯片内) |
缓存一致性 | 每个核心独立,与L3主从同步 | 每个核心独立,与L1/L3主从同步 | 多核共享 |
场景 | 需要立即执行的指令与高频访问的数据 | 稍低频但重复访问的数据 | 跨核心共享数据、大吞吐量计算 |
what is CacheLine?
CacheLine是CPU缓存中最小数据单元,当CPU从内存中读取数据时,会一次性加载64byte的数据,而不是只加载特定数据,即使只想读取1bit数据,也会加载64byte数据。这么做是因为,大多数情况下,数据都是顺序读取的,因此提前加载数据有利于减少延迟。
C#代码如何影响CPU缓存速度?
internal class Program
{
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
Rows();
sw.Stop();
Console.WriteLine($"逐行赋值执行时间:{sw.ElapsedMilliseconds}");
sw.Restart();
Columns();
sw.Stop();
Console.WriteLine($"逐列赋值执行时间:{sw.ElapsedMilliseconds}");
}
static void Rows()
{
int[,] tab = new int[5000, 5000];
for (int i = 0; i < 5000; i++)
{
for (int j = 0; j < 5000; j++)
{
tab[i, j] = 1;//逐行赋值,能成功利用到Cacheline提前加载的数据
}
}
}
static void Columns()
{
{
int[,] tab = new int[5000, 5000];
for (int i = 0; i < 5000; i++)
{
for (int j = 0; j < 5000; j++)
{
tab[j, i] = 1;//逐列赋值,无法利用Cacheline提前加载的数据,只能丢弃重新读取。
}
}
}
}
}
可以看到,非线性的数据检索带来了严重的性能问题,应当尽量避免对内存的非顺序访问。
杂七杂八系列----C#代码如何影响CPU缓存速度?的更多相关文章
- 第三章 - CPU缓存结构和java内存模型
CPU 缓存结构原理 CPU 缓存结构 查看 cpu 缓存 速度比较 查看 cpu 缓存行 cpu 拿到的内存地址格式是这样的 CPU 缓存读 根据低位,计算在缓存中的索引 判断是否有效 0 去内存读 ...
- 为什么CPU缓存会分为一级缓存L1、L2、L3?有什么意义?
https://baijiahao.baidu.com/s?id=1598811284058671259&wfr=spider&for=pc 简介:CPU缓存是CPU一个重要的组成部分 ...
- cpu缓存与多线程
一.cpu缓存结构 CPU速度远高于内存(即如果只考虑CPU和内存因素,程序的性能常常受到内存访问速度的限制,内存访问和运行),为了协调CPU和内存在速度上的差异,在CPU中增加了高速缓存.和计算机存 ...
- C和C++中的volatile、内存屏障和CPU缓存一致性协议MESI
目录 1. 前言2 2. 结论2 3. volatile应用场景3 4. 内存屏障(Memory Barrier)4 5. setjmp和longjmp4 1) 结果1(非优化编译:g++ -g -o ...
- 基于JVM原理、JMM模型和CPU缓存模型深入理解Java并发编程
许多以Java多线程开发为主题的技术书籍,都会把对Java虚拟机和Java内存模型的讲解,作为讲授Java并发编程开发的主要内容,有的还深入到计算机系统的内存.CPU.缓存等予以说明.实际上,在实际的 ...
- CPU缓存刷新的误解
即使是资深的技术人员,我经常听到他们谈论某些操作是如何导致一个CPU缓存的刷新.看来这是关于CPU缓存如何工作和缓存子系统如何与执行核心交互的一个常见误区.本文将致力于解释CPU缓存的功能以及执行程序 ...
- 从Java视角理解CPU缓存和伪共享
转载自:http://ifeve.com/from-javaeye-cpu-cache/ http://ifeve.com/from-javaeye-false-shari ...
- 写Java也得了解CPU–CPU缓存
CPU,一般认为写C/C++的才需要了解,写高级语言的(Java/C#/pathon…)并不需要了解那么底层的东西.我一开始也是这么想的,但直到碰到LMAX的Disruptor,以及马丁的博文,才发现 ...
- 【Java并发编程】从CPU缓存模型到JMM来理解volatile关键字
目录 并发编程三大特性 原子性 可见性 有序性 CPU缓存模型是什么 高速缓存为何出现? 缓存一致性问题 如何解决缓存不一致 JMM内存模型是什么 JMM的规定 Java对三大特性的保证 原子性 可见 ...
- 10 张图打开 CPU 缓存一致性的大门
前言 直接上,不多 BB 了. 正文 CPU Cache 的数据写入 随着时间的推移,CPU 和内存的访问性能相差越来越大,于是就在 CPU 内部嵌入了 CPU Cache(高速缓存),CPU Cac ...
随机推荐
- Draw.io:你可能不知道的「白嫖级」图表绘制神器
介绍 draw.io 是一个在 GitHub 上开源且拥有近十年发展历史的成熟项目,它是一款用于绘制 UML 图表的工具. 如果你曾经为流程图的绘制而流泪,又或是在夜里和UML大战到失眠, 不妨试试它 ...
- Ubuntu安装GPU驱动+CUDA+cuDNN的安装方法
一台有GPU的虚拟机如果没有安装CUDA的驱动,是需要我们手动去进行安装的,介绍Ubuntu操作系统的安装教程. 1. 下载安装文件 NVIDIA CUDA Toolkit Archive 点击上面链 ...
- Redis 原理 - String
String 数据结构 首先我来看下, Redis 中 String 的数据结构: 我们称之为 SDS (Simple Dynamic String) 简单动态字符串 struct sdshdr { ...
- 【软件】Ubuntu下QT的安装和使用
[软件]Ubuntu下QT的安装和使用 零.前言 QT是应用得比较广泛的程序框架,是因为其跨平台特性比较好,且用C/C++作为开发语言,性能也比较好,故本文介绍如何安装和使用QT,用的版本是QT 6. ...
- 学习unigui【25】关于图标
网上有不少介绍. 自己的经验: 是否需要下载文件fontawesome-free-6.5.1-web(),没有研究.说ext_js已经下载配套了. 我很懒,得过且过. 1.下载fontawesome- ...
- 一次windows下使用cmake遇到的问题
背景 在windows下的cmake和mingw提供的make,在windows环境下进行了简单尝试,结果发现make的时候失败: #include <iostream> int main ...
- 使用Python可视化洛伦兹变换
引言 大家好!今天我们将探讨一个非常有趣且重要的物理概念-洛伦兹变换.它是相对论的核心内容之一,描述了在高速运动下,时间.长度以及其他物理量是如何发生变化的.通过使用 Python 进行可视化,我们不 ...
- Redis 分布式锁的正确实现原理演化历程与 Redission的源码
当线程A,加锁并设置过期时间-->执行业务-->判断锁id完成后,但这时CPU线程调度其它工作了在这里卡住了, 而且也到了锁的过期时间了被动被删除,当线程B,加锁并设置过期时间--> ...
- JAVA基础之多线程三期--线程安全问题
一.线程安全问题就是指:多个线程并发访问同一个资源而发生安全性的问题, 线程安全问题都是由全局变量及静态变量引起的. 若每个线程中对全局变量.静态变量只有读操作,而无写 操作,一般来说,这个全局变量是 ...
- SpringBoot接口 - 统一异常处理
为什么要统一异常处理 如果不统一处理异常,程序开发时就需要在controller层写大量重复的Valid代码, 比如下面这个样子: @Slf4j @RestController public clas ...