计组实验5:cache大小测量与 cache line 大小测量

前言今天做了实验5,通过 c 语言测 cache 参数。其实按理来说挺简单的,只是我们班没给代码,纯靠自己。听说别的班有给代码emm 因为《深入理解计算机系统》这本书上面给的代码是 Linux 平台下的,而且需要一个 fcyc2 头文件,可以在 https://github.com/fabiensanglard/CpuCacheMountainViewer 这里找到。⚠我没有在 Linux 下试过课本上面的代码。。。我是在 win10 下测试的。。。所以 。。。我并不确定我的代码是否正确。
摘要由CSDN通过智能技术生成

前言

今天做了实验5,通过 c 语言测 cache 参数。其实按理来说挺简单的,只是我们班没给代码,纯靠自己。听说别的班有给代码

示例代码也有,在《深入理解计算机系统》这本书的 6.6 小结。

在这里插入图片描述

上面给的代码是 Linux 平台下的,而且需要一个 fcyc2 头文件,可以在 这里 找到。出于某些原因 我是懒狗 我并没有用这份代码,我想在 win10 下进行测试。



我没有在 Linux 下试过课本上面的代码。。。
我是在 win10 下测试的。。。
所以 。。。
我并不确定我的代码是否正确。。。
请谨慎食用 Orz

注意事项(⚠ 重要)

唔。。。。我再编辑下,因为这个实验在 win10 下不是特别容易成功,有很多值得注意的地方:

  1. 请不要使用 visual studio 这个 IDE,因为它是大聪明,会优化掉你的代码。
  2. 最好使用 dev c++ 这个 IDE,并且开启 std c++11 才能完整地运行代码

开启方法:
在这里插入图片描述

  1. 最好增大测试的次数,114514190 就是一个好数字!
  2. 不要使用 rand() 这些小随机数生成器
  3. 不要在最内层循环直接生成随机数,因为生成随机数时间远大于访问内存,这样最多只能测出 L3 的大小别问我怎么知道的
  4. 运行时最好关闭所有应用程序,什么秋秋,微信,网抑云,关掉统统关掉! 防止 cpu 抢占
  5. 可以通过 CPU-Z 这个软件查询精确的缓存大小,但是 emmm 因为我的代码不能够精确地测出 L1 数据缓存和 cache Line 的大小,于是我就用任务管理器糊弄一下就交了报告。。。
  1. 实验的几个参数最好起不同的变量名。比如随机数的范围就是数组大小,而访问次数应该被设定为一个常数(比如 114514190)
  2. 虔诚地跪拜姿势,点击启动运行按钮
  3. 我编不下去了 Orz

总之就是很玄学 祝大家实验顺利。。。 我先 run 了(逃

实验说明

增进对cache工作原理的理解

体验程序中访存模式变化是如何影响 cahce 效率进而影响程序性能的过程;学习在 X86 真实机器上通过调整程序访存模式来探测多级 cache 结构以及 TLB 的大小。

按照下面的实验步骤及说明,完成相关操作记录实验过程的截图:

  1. x86 cache 层次结构的测量:
    首先设计一个用于测量 x86 系统上 cache 层次结构的方案然后设计出相应的代码;然后,运行你的代码获得相应的测试数据。最后,根据测试数据分析你的x86机器有几级cache,各自容量是多大。
  2. 选做:尝试测量你 L1 cache 行的大小
  3. 选做:尝试测量你的 x86 机器 TLB 有多大

要求 1(90分)(报告撰写质量10分)

实验步骤

cache 层级的测量

首先测量我们的电脑 cache 的层级关系。我的方案是这样的:

  1. 开辟一块大小为 size kb 的内存空间
  2. 进行若干次随机内存访问
  3. 记录时间,计算平均的数据吞吐量(kb/s)
  4. 画图分析,记录 size 与 kb/s 的关系

注:
随机数生成,不要用 rand() 口牙,rand() 范围为 0~32768 好像,这才 30k 不到
我们随机访问是要产生大量随机且有意义的内存访问,要完全覆盖内存,这样才能使得内存尽可能被装进 cache 里面,这意味着随机数的范围需要非常大
要用 c++11 的 uniform_int_distribution
详见下文代码部分~

可行性分析:因为我们使用完全随机的地址进行内存访问,那么:

  1. 如果该内存能够被完整装入 cache,我们只需要花费很少的时间就可以访问到
  2. 如果内存块大小 size 超过我们的 cache 大小,即当前内存块不能被完整的放入 cache,那么我们的随机访问时间就会大大增加,因为发生了 miss

在这里插入图片描述
所以根据以上的两个分析,我们通过观察【吞吐量/数据集】大小的图表,就能分析出对应的 cahce 的大小和层次结构。

我使用 std c++ 11 在 Windows10 系统上进行实验,IDE 使用 dev c++,未开启任何 O1,O2 优化。

我们编写一个函数名叫 random_access,他会根据参数 size 的大小,创建一块大小为 size byte 的内存空间,并且进行 114514190 次随机访问,并且输出吞吐量(单位为 kb/s)。

void random_access(int size)
{
   
	int n = size / sizeof(char);
	char* buffer = new char[n];
	fill(buffer, buffer+n, 1);
	
	uniform_int_distribution<> dis(0, n-1);
	
	int test_times = 11451419 * 10;
	
	vector<int> random_index;
	for(int i=0; i<test_times; i++)
	{
   
		int index = dis(gen);
		random_index.push_back(index); 
	}
	
	int sum = 0;
	high_resolution_clock::time_point t1 = high_resolution_clock::now();
	for(int i=0; i<test_times; i++)
	{
   
		sum += buffer[random_index[i]];
	}
	high_resolution_clock::time_point t2 = high_resolution_clock::now();
	duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
	double dt =
  • 24
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
在 C 语言中,获取 cacheline大小需要使用特定的操作系统相关的函数或者编译器相关的宏。以下是一些常见的方法: 1. 使用 Linux 系统的 sysconf() 函数获取 cacheline 大小: ```c #include <unistd.h> #include <stdio.h> int main() { long cacheline_size = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); printf("cacheline size on this system is %ld bytes\n", cacheline_size); return 0; } ``` 2. 使用 GCC 编译器的 __builtin_cpu_supports() 函数获取 cacheline 大小: ```c #include <stdio.h> #include <stdint.h> #include <stdbool.h> int main() { bool has_cacheline_size = false; uint32_t size = 0; if (__builtin_cpu_supports("avx")) { size = __builtin_ia32_cpuid_count(0x80000006, 0, &eax, &ebx, &ecx, &edx); if (size && (eax & 0xff) > 0) { has_cacheline_size = true; size = (eax & 0xff) * 64; } } if (has_cacheline_size) { printf("cacheline size on this system is %u bytes\n", size); } else { printf("cannot determine cacheline size on this system\n"); } return 0; } ``` 注意:这个方法需要编译器支持 AVX 指令集。 3. 使用 Windows 系统的 GetLogicalProcessorInformation() 函数获取 cacheline 大小: ```c #include <windows.h> #include <stdio.h> int main() { PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL; DWORD length = 0; BOOL result = GetLogicalProcessorInformation(buffer, &length); if (!result && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(length); result = GetLogicalProcessorInformation(buffer, &length); } if (result) { DWORD offset = 0; while (offset < length) { PSYSTEM_LOGICAL_PROCESSOR_INFORMATION info = buffer + offset / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); if (info->Relationship == RelationCache && info->Cache.Level == 1 && info->Cache.Type == CacheData) { printf("cacheline size on this system is %u bytes\n", info->Cache.LineSize); break; } offset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION); } } else { printf("cannot determine cacheline size on this system\n"); } free(buffer); return 0; } ``` 注意:这个方法需要在 Windows 系统上运行。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值