C#代码如何影响CPU缓存速度?

CPU与RAM的隔阂

CPU与RAM是两个独立的硬件,并非集成在一起。所以他们两个之间一定会存在一个连接的桥梁,这个桥梁的名字叫做内存总线。

内存总线由三部分组成:

  1. 地址总线(Address Bus)
    用于传输内存地址,也就是我们经常看到的0X77F84FAB这种类似的内存地址,一根总线代表一个电信号,一个电信号能传递高电平/低电平两种信息,用二进制表示就是1/0。因此总线数量的多少决定了可以传递内存地址的大小,比如你有32根总线,就代表你总线宽度32。2^32=4294967296,等于4GB内存,这就是32位操作系统只支持4G内存的由来。

  2. 数据总线(Data Bus)
    用于传输数据,原理同上,一根总线代表1bit传输段位,64根总线就是 64bit=8byte。一次性可以传输8byte单位的数据。

  3. 控制总线(Control Bus)
    用户传输控制信号,比如一根用来"读信号输出"的开关,一根"写信号输出"的开关。一根"时钟信号"的开关

更详细可以参考此文:汇编语言学习笔记(一)基础知识 - 叫我安不理 - 博客园

CPU Cache

可以看到,假设CPU要读取1kb的数据,你的数据总线总线只有64根,1024/8=128,你需要来回倒腾128次,才能读取完毕,这一来二去就加大了内存之间的延迟,为了优化此性能瓶颈,
CPU除了寄存器外临时存储数据,还内置了Cache来临时存储数据与指令。

游戏神U 9800x3d就是依靠96MB的"巨大L3缓存",来降低了内存延迟,从而在游戏场景默秒全Intel

特性L1缓存L2缓存L3缓存
速度1-2纳秒约10纳秒约30纳秒
容量几十KB到几百KB几百KB到几MB几MB到几十MB
位置集成在 CPU 核心内部每个核心独立拥有(位于核心附近)多核共享(位于 CPU 芯片内)
缓存一致性每个核心独立,与L3主从同步每个核心独立,与L1/L3主从同步多核共享
场景需要立即执行的指令与高频访问的数据稍低频但重复访问的数据跨核心共享数据、大吞吐量计算

image

what is CacheLine?
CacheLine是CPU缓存中最小数据单元,当CPU从内存中读取数据时,会一次性加载64byte的数据,而不是只加载特定数据,即使只想读取1bit数据,也会加载64byte数据。这么做是因为,大多数情况下,数据都是顺序读取的,因此提前加载数据有利于减少延迟。

眼见为实

使用Coreinfo 来观察CPU

image

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提前加载的数据,只能丢弃重新读取。
                }
            }
        }
    }
}

image

可以看到,非线性的数据检索带来了严重的性能问题,应当尽量避免对内存的非顺序访问。

行业拓展

分享一个面向研发人群使用的前后端分离的低代码软件——JNPF

基于 Java Boot/.Net Core双引擎,它适配国产化,支持主流数据库和操作系统,提供五十几种高频预制组件,内置了常用的后台管理系统使用场景和实用模版,通过简单的拖拉拽操作,开发者能够高效完成软件开发,提高开发效率,减少代码编写工作。

JNPF基于SpringBoot+Vue.js,提供了一个适合所有水平用户的低代码学习平台,无论是有经验的开发者还是编程新手,都可以在这里找到适合自己的学习路径。

此外,JNPF支持全源码交付,完全支持根据公司、项目需求、业务需求进行二次改造开发或内网部署,具备多角色门户、登录认证、组织管理、角色授权、表单设计、流程设计、页面配置、报表设计、门户配置、代码生成工具等开箱即用的在线服务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值