Tag: 缓存

缓存内存如何工作?

今天,当我在计算机组织课上时,老师谈到了一些有趣的事情。 谈到为什么缓存有效时,他说: for (i=0; i<M; i++) for(j=0; j<N; j++) X[i][j] = X[i][j] + K; //X is double(8 bytes) 用第二行改变第一行是不好的。 你对此有何看法? 为什么会这样?

这些二维arrays中的哪一个有利于使用,为什么?

在facebook小组中,我看到了一个类似的问题: 如果一行在下面的二维数组中占主导地位,哪一个是有利的,为什么呢? a) for(i=0;i<1000;i++) for(j=0;j<1000;j++) temp=temp+a[i][j]; b) for(j=0;j<1000;j++) for(i=0;i<1000;i++) temp=temp+a[i][j] 从我的观点来看,我可以看出上述两个陈述没有区别。 我想这些都是一样的。 如果我错了,请纠正我?

强制L1缓存上的一些数据

对这个简单的问题抱歉。 仍在努力解决这里的一些记忆概念。 问题是:假设我有一个我想重复访问的预先计算的数组A. 有没有办法告诉C程序让这个数组尽可能接近CPU缓存以便最快地访问? 谢谢。

虚假共享和primefaces变量

当不同的变量位于同一个缓存行中时,您可能会遇到False Sharing ,这意味着即使两个不同的线程(在不同的核心上运行)正在访问两个不同的变量,如果这两个变量位于同一个缓存行中,您将拥有性能命中,因为每次都会触发缓存一致性。 现在说这些变量是primefaces变量(primefaces我指的是引入内存栅栏的变量,比如C ++的atomic ),会在那里进行虚假共享,或者primefaces变量是否在同一个缓存行中并不重要或者不是,据说他们无论如何都会引入缓存一致性。 换句话说,将primefaces变量放在同一个缓存行中会使应用程序变慢而不是将它们放在同一个缓存行中吗?

每个内存访问Xeon带入缓存的字节数是多少?

我正在开发一个用C ++编写的系统,在Linux上的Xeon上运行,需要尽可能快地运行。 在RAM中保存的大型数据结构(基本上是结构数组)超过10 GB,并且需要定期访问它的元素。 我想修改数据结构以尽可能地使用系统的缓存机制。 目前,访问大多是在整个结构中随机进行的,每次读取1-4个32位的整数。 在另一次读取发生在同一个地方之前很长一段时间,因此缓存没有任何好处。 现在我知道当你从RAM中的随机位置读取一个字节时,不仅仅是那个字节被带入缓存。 我的问题是引入了多少字节? 是16,32,64,4096吗? 这被称为缓存线吗? 我希望重新设计数据结构,以最大限度地减少随机RAM访问,并使用缓存而不是缓存。 知道在随机访问中将多少字节拉入缓存将告知我所做的设计选择。 更新(2014年10月):在我提出上述问题后不久,该项目被搁置。 它已经恢复并基于下面答案中的建议,我进行了一些围绕RAM访问的实验,因为似乎TLB捶打可能正在发生。 我修改了程序以运行大页面(2MB而不是标准的4KB),观察到一个小的加速,大约2.5%。 我找到了关于在这里和这里设置大页面的很好的信息。

L1内存带宽:使用相差4096 + 64字节的地址,效率下降50%

我想用英特尔处理器实现以下操作的最大带宽。 for(int i=0; i<n; i++) z[i] = x[i] + y[i]; //n=2048 其中x,y和z是浮点数组。 我在Haswell,Ivy Bridge和Westmere系统上这样做。 我最初分配了这样的内存 char *a = (char*)_mm_malloc(sizeof(float)*n, 64); char *b = (char*)_mm_malloc(sizeof(float)*n, 64); char *c = (char*)_mm_malloc(sizeof(float)*n, 64); float *x = (float*)a; float *y = (float*)b; float *z = (float*)c; 当我这样做时,我获得了每个系统预期的峰值带宽的大约50%。 峰值计算为frequency * average bytes/clock_cycle 。 每个系统的平均字节/时钟周期为: Core2: two 16 byte reads one […]

多个线程和CPU缓存

我正在使用多个线程在C中实现图像过滤操作,并使其尽可能优化。 我有一个问题:如果一个内存被thread-0访问,并且如果同一个内存被thread-1访问,它是否会从缓存中获取它? 这个问题源于这两个线程可能运行到CPU的两个不同核心的可能性。 因此,另一种方法是:所有内核是否共享相同的公共缓存? 假设我有如下的内存布局 int输出[100]; 假设有2个CPU核心,因此我产生两个线程同时工作。 一种方案可以是将内存分成两个块,0-49和50-99,并让每个线程在每个块上工作。 另一种方法可能是让线程0在偶数索引上工作,比如0 2 4等等……而另一个线程工作在奇数索引上,比如1 3 5 ……这个后来的技术更容易实现(特别适用于3D)数据)但我不确定我是否可以通过这种方式有效地使用缓存。

WBINVD指令用法

我正在尝试在linux上使用WBINV指令来清除处理器的L1缓存。 以下程序编译,但在我尝试运行它时会产生分段错误。 int main() {asm (“wbinvd”); return 1;} 我正在使用gcc 4.4.3并在我的x86机器上运行Linux内核2.6.32-33。 处理器信息:Intel(R)Core(TM)2 Duo CPU T5270 @ 1.40GHz 我按如下方式构建了程序: $ gcc $ ./a.out 分段故障 有人能告诉我我做错了什么吗? 我如何让它运行? PS:我正在运行一些性能测试,并希望确保处理器缓存的先前内容不会影响结果。

如何在不触摸缓存的情况下写入或读取内存

有没有办法在不触及x86 CPU下的L1 / L2 / L3缓存的情况下写入/读取内存? 是否完全由硬件管理的x86 CPU缓存? 编辑:我想这样做,因为我想采样内存的速度,看看内存的任何部分性能是否下降。

数组结构和结构数组 – 性能差异

我有一个这样的课: //Array of Structures class Unit { public: float v; float u; //And similarly many other variables of float type, upto 10-12 of them. void update() { v+=u; v=v*i*t; //And many other equations } }; 我创建了一个Unit类型的对象数组。 并调用它们的更新。 int NUM_UNITS = 10000; void ProcessUpdate() { Unit *units = new Unit[NUM_UNITS]; for(int i = 0; i < […]