缓存着色 Page color测试
根据
7个示例科普CPU CACHE
测试缓存着色
E3 1230v2, L2缓存:4* 256KB 8way (1MB)
cacheline 64B,页大小64KB,1页含有1024cacheline。
set数量=1MB/64/8=2048.
根据文中所述,2KB*64=128K,(理解不够深,不晓得算对没有)
每128K的物理内存会映射到同一个cache slot上竞争,这个slot容量是8.
enum {BufferSize = 1024 * 1024 * 1
};
#include <iostream>
#include <type_traits>
#include <windows.h>
#include <intrin.h>
#include <vector>
char clearcachebuff[1024 * 1024 * 8];
std::vector<char> buff1;
std::vector<char> buff2;
void clear_cache(int i)
{unsigned int junk = 0;auto t = __rdtscp(&junk);memset(clearcachebuff, i, sizeof(clearcachebuff));t = __rdtscp(&junk) - t;//printf(" clear cache %d\n", (int)t / 1024);
}
static long UpdateEveryKthByte(std::vector<char>& buff, int K)
{clear_cache(rand());unsigned int junk = 0;auto t = __rdtscp(&junk);const int rep = 1024 * 1024; // Number of iterations – arbitrarychar* parr = &buff[0];int size = buff.size();int p = 0;for (int i = 0; i < rep; i++){parr[p + (i & 31)]++; // & 31 动态量防cpu固定偏移猜测p += K;//_mm_prefetch(parr + p + K, _MM_HINT_T0);if (p >= size) p = 0;}return long(__rdtscp(&junk) - t);
}int main()
{unsigned int junk = 0;buff1.resize(BufferSize);buff2.resize(BufferSize * 2);printf("每jump数值读取内存, 对于每个jump测试3次,打印相对耗时。\n缓冲区%dMB和%dMB\n", buff1.size() / 1024 / 1024, buff2.size() / 1024 / 1024);for (int i = 1; i <= 1024 * 128; i *= 2){auto jump = i * 53 / 64;printf(" jump:%7d Buff1:", jump);printf(" %6d", UpdateEveryKthByte(buff1, jump) / 1024);printf(" %6d", UpdateEveryKthByte(buff1, jump) / 1024);printf(" %6d", UpdateEveryKthByte(buff1, jump) / 1024);printf(" Buff2:");printf(" %6d", UpdateEveryKthByte(buff2, jump) / 1024);printf(" %6d", UpdateEveryKthByte(buff2, jump) / 1024);printf(" %6d", UpdateEveryKthByte(buff2, jump) / 1024);puts("");jump = i;printf("*jump:%7d Buff1:", jump);printf(" %6d", UpdateEveryKthByte(buff1, jump) / 1024);printf(" %6d", UpdateEveryKthByte(buff1, jump) / 1024);printf(" %6d", UpdateEveryKthByte(buff1, jump) / 1024);printf(" *Buff2:");printf(" %6d", UpdateEveryKthByte(buff2, jump) / 1024);printf(" %6d", UpdateEveryKthByte(buff2, jump) / 1024);printf(" %6d", UpdateEveryKthByte(buff2, jump) / 1024);puts("");jump = i * 66 / 64;printf(" jump:%7d Buff1:", jump);printf(" %6d", UpdateEveryKthByte(buff1, jump) / 1024);printf(" %6d", UpdateEveryKthByte(buff1, jump) / 1024);printf(" %6d", UpdateEveryKthByte(buff1, jump) / 1024);printf(" Buff2:");printf(" %6d", UpdateEveryKthByte(buff2, jump) / 1024);printf(" %6d", UpdateEveryKthByte(buff2, jump) / 1024);printf(" %6d", UpdateEveryKthByte(buff2, jump) / 1024);puts("");}
}
输出为(除了jump,其他数值均为一千个cpu周期,比如4924代表4924千周期,可知循环每步消耗4.9个cpu周期):
每jump数值读取内存, 对于每个jump测试3次,打印相对耗时。
缓冲区1MB和2MBjump: 0 Buff1: 4924 4737 4717 Buff2: 4747 5049 5095
*jump: 1 Buff1: 4691 4693 4725 *Buff2: 4695 4690 5533jump: 1 Buff1: 4890 4833 5045 Buff2: 4806 4733 4786jump: 1 Buff1: 4817 5367 4704 Buff2: 4834 4989 4926
*jump: 2 Buff1: 4911 4821 5086 *Buff2: 4698 4699 4746jump: 2 Buff1: 4641 4746 4718 Buff2: 4696 4843 4703jump: 3 Buff1: 4771 4674 4687 Buff2: 4667 4730 4763
*jump: 4 Buff1: 4648 5483 4685 *Buff2: 5291 4709 4727jump: 4 Buff1: 4842 4616 5001 Buff2: 4780 4644 4676jump: 6 Buff1: 4898 4744 4754 Buff2: 5178 4707 4877
*jump: 8 Buff1: 4657 5065 4697 *Buff2: 5254 5350 4795jump: 8 Buff1: 4773 4722 4656 Buff2: 4669 5181 4716jump: 13 Buff1: 4985 4979 5036 Buff2: 4908 4891 4968
*jump: 16 Buff1: 4860 4849 4697 *Buff2: 4954 7003 5111jump: 16 Buff1: 4981 4787 4672 Buff2: 5042 5208 5223jump: 26 Buff1: 6065 5175 5414 Buff2: 6464 5683 5388
*jump: 32 Buff1: 6336 5598 5558 *Buff2: 6516 5948 5612jump: 33 Buff1: 6318 6193 6260 Buff2: 6774 6175 5883jump: 53 Buff1: 8281 7958 7894 Buff2: 11367 8027 8106
*jump: 64 Buff1: 9686 8846 8730 *Buff2: 11110 10006 8855jump: 66 Buff1: 10131 8895 8684 Buff2: 10781 9173 8875jump: 106 Buff1: 10278 9601 9207 Buff2: 10900 9352 9578
*jump: 128 Buff1: 9119 9045 9015 *Buff2: 9488 9176 9863jump: 132 Buff1: 8961 8642 8742 Buff2: 9445 9111 9324jump: 212 Buff1: 8046 8056 8804 Buff2: 9760 9128 9251
*jump: 256 Buff1: 8891 8834 10498 *Buff2: 9162 8945 9046jump: 264 Buff1: 7737 7353 8047 Buff2: 8935 9660 9196jump: 424 Buff1: 6245 6510 6811 Buff2: 7670 7182 7415
*jump: 512 Buff1: 9068 9058 8821 *Buff2: 8732 9195 10241jump: 528 Buff1: 6410 6150 6462 Buff2: 6548 6594 6360jump: 848 Buff1: 6173 6786 6586 Buff2: 6495 5980 6028
*jump: 1024 Buff1: 10959 12582 11729 *Buff2: 11751 11693 11527jump: 1056 Buff1: 6233 6147 6200 Buff2: 6222 6165 6340jump: 1696 Buff1: 6628 6123 6132 Buff2: 6350 6230 6237
*jump: 2048 Buff1: 14240 14012 14062 *Buff2: 15153 14452 14133jump: 2112 Buff1: 5617 5028 5447 Buff2: 6621 6216 6076jump: 3392 Buff1: 5096 5076 6490 Buff2: 6171 6510 6169
*jump: 4096 Buff1: 17242 17716 17222 *Buff2: 17829 17342 17223jump: 4224 Buff1: 5324 5068 5045 Buff2: 6234 6274 6088jump: 6784 Buff1: 5048 5010 5060 Buff2: 6077 6406 6149
*jump: 8192 Buff1: 17002 17483 17315 *Buff2: 19475 17946 18244jump: 8448 Buff1: 4987 5112 5307 Buff2: 6118 6176 6180jump: 13568 Buff1: 4892 4861 4934 Buff2: 6132 6237 6323
*jump: 16384 Buff1: 16980 17361 17246 *Buff2: 19211 18657 18046jump: 16896 Buff1: 4690 4690 4673 Buff2: 6064 6224 6067jump: 27136 Buff1: 4690 4647 4698 Buff2: 5820 5620 6144
*jump: 32768 Buff1: 11719 11759 11568 *Buff2: 17638 17688 17567jump: 33792 Buff1: 8039 8120 8035 Buff2: 10058 10515 9967jump: 54272 Buff1: 4673 5022 4724 Buff2: 8816 7979 8715
*jump: 65536 Buff1: 13166 12643 13971 *Buff2: 11876 11878 11797jump: 67584 Buff1: 4709 5107 4633 Buff2: 8936 10220 8958jump: 108544 Buff1: 4836 4718 4890 Buff2: 7238 7141 6939
*jump: 131072 Buff1: 5015 5015 5015 *Buff2: 14106 13760 13943jump: 135168 Buff1: 4909 5018 4674 Buff2: 10131 9988 9293
每跳过jump字节,访问内存。看输出易得整2次幂的跳过,性能都很慢,这是因为如此访问的内存很容易竞争相同的cache slot导致前面缓存失效。
131072=128K = 1/8 L2,正好整个循环中只会访问到8个char,而L2是8way的因此全部放入同一个slot没有溢出,所以性能极高。(循环每步4.6周期).对于结果中出现的19周期,猜测是L3的功效,否则时间将低至45周期。
这告诉我们什么?如果内存中有512KB的大型数据结构×32个实例,如
struct MyArray
{int usedSize = 0;char buff[512 * 1024 - 1000];
};
每当访问这个大型数据结构时,往往要访问usedSize,而512KB的大型数据结构通常对齐到页首。
如此顺序访问32个MyArray的usedSize时,每当访问一个usedSize就会将某一个实例的usedSize踢出缓冲区。1MB大的L2缓冲区容不下第9个usedSize。
解决方案,故意将usedSize随机对齐到页首的+ 随机值 * 64字节?
另一方面反向应用:将8个实例全部对齐到一个slot中,而安排其他内存尽量不映射到这个slot或顺序遍历内存,这样从概率上更不容易将这8个实例踢出缓冲区?
缓存着色 Page color测试相关推荐
- 读取文件慢_页面缓存(Page Cache)-内存和文件之间的那点事儿(下)
原文:https://manybutfinite.com/post/page-cache-the-affair-between-memory-and-files/ 翻译:RobotCode俱乐部 现在 ...
- 什么是页缓存(Page Cache)(转载)
我们知道文件一般存放在硬盘(机械硬盘或固态硬盘)中,CPU 并不能直接访问硬盘中的数据,而是需要先将硬盘中的数据读入到内存中,然后才能被 CPU 访问. 由于读写硬盘的速度比读写内存要慢很多(DDR4 ...
- SpringBoot高级-缓存-搭建redis环境测试
实际开发中我们用的是缓存中间件,比如我们经常使用的Redis,memcache,包括ehcache,我们都是用一些缓存中间件,Springboot支持很多缓存的配置,而默认开启的是SimpleCach ...
- linux buffer 刷到磁盘,Linux下的磁盘缓存 linux page buffer cache深入理解
延伸:linux page buffer cache深入理解 描述:...么我们在分析io问题的时候可能会更加得心应手. Page cache实际上是针对文件系统的,是文件的缓存,在文件层面上的数据会 ...
- 22-09-20 西安 谷粒商城(04)Redisson做分布式锁、布隆过滤器、AOP赋能、自定义注解做缓存管理、秒杀测试
Redisson 1.Redisson做分布式锁 分布式锁主流的实现方案: 基于数据库实现分布式锁 基于缓存(Redis),性能最高 基于Zookeeper,可靠性最高 Redisson是一个在Re ...
- mysql 测试 缓存_mysql 缓存开启及测试
mysql高速缓存相关参数设置 查看mysql cache功能是否开启: show variables like '%query_cache%';结果如下 如果query_cache_type=ON, ...
- 文件缓存page cache
address_space结构 host:指向当前 address_space 对象所属的文件 inode 对象 page_tree:用于存储当前文件的 页缓存 rb_boot i_mmap存储着共 ...
- 测试环境启动时候进行清空redis所有缓存操作的java代码
目录 目的: 1.调用代码逻辑如下:java-code 2.redis的事务处理,要小心重构掉!对于原子性原则上不进行破坏! 3.依赖Pom的配置 目的: 测试环境要重构的时候,会把所有的常量redi ...
- 谈谈varnish、squid、apache、nginx缓存的对比
1.Squid,很古老的反向代理软件,拥有传统代理.身份验证.流量管理等高级功能,但是配置太复杂.它算是目前互联网应用得最多的反向缓存代理服务器,工作于各大古老的cdn上. 2.Varnish是新兴的 ...
最新文章
- 力扣(LeetCode)刷题,简单+中等题(第30期)
- 从零写一个编译器(七):语义分析之符号表的数据结构
- C语言 vprintf 函数 - C语言零基础入门教程
- 【递归】剑指offer——面试题19:二叉树的镜像
- NYOJ 个人刷题题解
- 假设某台台式计算机的内存储器容量为128,假设某台计算机的内存储器容量为128MB,硬盘容量为10GB,硬盘的容量是内存容量的多少倍?...
- 《数据库原理MySQL》第三次上机实验
- 快手用户群体分析_抖音、快手竞品分析报告
- 电商项目的类目,spu,sku,单品
- 资源监视器中看不到磁盘队列等等问题的解决方案
- android图片轮播序号,求一组详细的图片轮播HTML代码(图片下面标有图片序号,鼠标点击相应序号,播放所对应图片;鼠标点击图片时链接到相应页面) 和一些电子商务网站首页的广告差不多...
- 学点负面情绪的抗争能力
- Kubernetes集群部署篇( 一)
- 我知道的几个免费的API数据接口
- pinia使用与如何安装详解详细教程
- Python爬虫进阶之字体反扒保姆级教程!
- 土壤湿度指标(Soil wetness index,SWI)
- 微软研发经理邹欣谈IT教育:推荐《我是一只IT小小鸟》
- Altium Desinger 20概述-安装及卸载
- 计算机基础教程张福炎pdf,计算机基础教学大纲(理科).pdf
热门文章
- 浅谈情报的实践与落地
- 在ibatis中查询返回List集合的问题
- 打了三年ACM,拿了几个金牌
- 神舟电脑装linux双系统,神舟+win10+ubuntu16.04+256GSSD+1THHD双系统安装加openssl踩坑之旅...
- Libav、FFmpeg、mplayer、VLC开源项目、FFDshow
- QQ每天定时领取群礼物
- IBM ThinkPad 笔记本产品系列简介
- javafx vbox 居中_如何平均分配JavaFX VBox的元素
- matlab 微分方程组参数拟合,如何拟合微分方程组的参数?
- 怎样关闭笔记本触控板