您的位置:首页 > 财经 > 金融 > 广州越秀区天气预报_从哪里找外贸公司电话_网站联盟营销_西安seo公司

广州越秀区天气预报_从哪里找外贸公司电话_网站联盟营销_西安seo公司

2024/11/16 22:36:07 来源:https://blog.csdn.net/hebhljdx/article/details/142657422  浏览:    关键词:广州越秀区天气预报_从哪里找外贸公司电话_网站联盟营销_西安seo公司
广州越秀区天气预报_从哪里找外贸公司电话_网站联盟营销_西安seo公司

引言

在许多文章中指出了这些缓存的架构,速度差异等。纸上得来终觉浅,今天想实际写代码简单测试一下。

背景

现代计算机系统中,CPU缓存(L1、L2、L3)和主内存(RAM)之间的读取速度有着显著的差异。缓存的主要目的是提高数据访问的速度,从而提升整体的系统性能。本篇文章将通过一系列的测试来探索不同大小内存块的读写性能,从而揭示缓存和内存之间读取速度的变化规律。

在这里插入图片描述

测试思路

我们通过改变内存块的大小来观察缓存命中和未命中的情况。具体而言,我们会从小块内存(128字节)开始测试,逐渐增加到较大的内存块(10GB),以此来观察性能曲线的变化。

测试代码

以下是用于测试的C++代码:

#include <iostream>
#include <vector>
#include <chrono>
#include <cstdlib>// 记录读写操作的时间
void testMemoryAccessSpeed(size_t blockSize) {size_t totalBytes = 1024ull * 1024 * 1024 * 100; // 总共读写100GB的数据size_t iterations = totalBytes / blockSize;std::vector<size_t> buffer(blockSize / sizeof(size_t));// 初始化计时器auto start = std::chrono::high_resolution_clock::now();// 执行读写操作for (size_t i = 0; i < iterations; ++i) {memset(buffer.data(), 551546, buffer.size() * sizeof(size_t));}// 记录结束时间auto end = std::chrono::high_resolution_clock::now();auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);// 输出结果if (blockSize > 1024 * 1024) {std::cout << "Block Size (MB): " << blockSize / 1024 / 1024 << ", Time (ms): " << duration.count() << " Loops:"<< iterations << std::endl;}else if (blockSize > 1024) {std::cout << "Block Size (KB): " << blockSize / 1024 << ", Time (ms): " << duration.count() << " Loops:" << iterations << std::endl;}else {std::cout << "Block Size ( B): " << blockSize << ", Time (ms): " << duration.count() << " Loops:" << iterations << std::endl;}
}int main() {// 测试不同大小的内存块std::vector<size_t> blockSizeVec = {128, 512, 1024, 2 * 1024, //128B ~ 2KB4 * 1024, 64 * 1024, 512 * 1024, 4 * 1024 * 1024,  // 4KB ~ 4 MB16 * 1024 * 1024, 64 * 1024 * 1024, 256 * 1024 * 1024, 512 * 1024 * 1024,  // 16M ~ 512M1024 * 1024 * 1024, 2ull * 1024 * 1024 * 1024, 5ull * 1024 * 1024 * 1024, 10ull * 1024 * 1024 * 1024  // 1G ~ 10G};const size_t maxBlockSize = 128 * 1024 * 1024; // 最大到128MBfor (auto it : blockSizeVec) {testMemoryAccessSpeed(it);}return 0;
}

测试的硬件平台为:

在这里插入图片描述
在这里插入图片描述

测试结果

以下是测试代码的输出:
在这里插入图片描述

结果粗略评估和解释

  1. 超小块内存(小于1KB)

    • 当内存块较小(如128字节)时,需要执行的循环次数成倍增加,整体的耗时更多在循环指令和函数调用(memset)上,而非数据读取。
    • 随着内存块大小的增加,循环次数减少,内存读写开始成为瓶颈,数据开始有意义。
  2. 小块内存(1KB至4KB)

    • 当内存块较小时,读写操作主要发生在L1缓存中,因此时间较长。
    • 随着内存块大小的增加,L1缓存的利用率下降,但L2缓存开始发挥作用,因此时间逐渐增加。
  3. 中等大小内存块(4KB至4MB)

    • 在这个范围内,L2缓存成为主要存储介质,性能较高。
    • 当内存块大小增加到一定程度,L2缓存开始饱和,性能下降。
  4. 大块内存(4MB至30MB)

    • L3缓存成为主要存储介质,性能再次提高。
    • 当内存块进一步增加到几十MB时,L3缓存也逐渐饱和,性能趋于稳定。
  5. 超大块内存(30MB及以上)

    • 超过L3缓存的容量后,性能受内存读取速度的限制,因此时间较为稳定。

excel 作图分析

在这里插入图片描述
在上图中,红色参考线是根据CPU-Z给出的单核心最大的L1~L3的缓存大小参考。注意,横坐标的BlockSize的增长不是线性增长的,但纵坐标轴Time是线性的。

从上图可以根据Time来粗略评估L1~L3再到内存的性能,我们选取了这几个样本点作为各个缓存性能的代表:
在这里插入图片描述

我的测试结论

根据选取的样本点,即可得出不同存储类型的性能参考:
在这里插入图片描述

上面的L1数据不是特别严谨,因为在块较小时,在循环和函数调用上会有额外的耗时,因此L1的性能应该比测试数据更高。具体高多少,可以根据前面的超小块内存测试结果进行评估。

网上其他相关测试的结论

在这里插入图片描述
在这里插入图片描述

总结

综合网上的资料和我的实践结论,基本可以得出如下概念:

  1. L1的速度是L2的2~5倍,我的测试结果是3.8倍
  2. L2的速度是L3的2~3倍,我的测试结果是1.8倍
  3. L3的速度是内存的3~7倍,我的测试结果是2.4倍(DDR5@4000M)。

这里的性能测试结果仅仅是上面的代码的运行耗时结果,不代表在大部分场景下L3的性能比内存高3~7倍。CPU访问内存需要经过复杂的内存控制器,主板的内存总线,再到内存控制器等复杂路径,每次读写也要操作一系列内存寄存器,从程序的角度来看,读写内存的延时要远远大于L3。从上图AIDA的测试结果中也能看出,内存的延时是L3的十倍。
对于实际程序运行的情况,内存延时带来的耗时增加是更严重的,这也是现代CPU把L3缓存做到30MB这么大的重要原因。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com