1
2
计算机通常使用 隐藏物 帮助加速对主存储器的访问。 通常用于主存储器的硬件速度相对较慢,从主存储器到处理器的数据可能需要许多处理器周期。因此,计算机通常包括一个较小的数量,非常快,但昂贵的内存称为缓存。计算机可能有几个层次的高速缓存,其中一部分内置于处理器或处理器芯片本身,另一部分则在处理器芯片之外。 由于缓存较小,它不能将所有内容都保存在主内存中。它甚至不能保存一个程序正在使用的所有内容。因此,处理器必须决定缓存中保存的内容。 程序最常访问的地方是内存中的连续位置。通常,程序读取数组的元素237后,很快就会读取238,然后再读取239,依此类推。它很少读7024,只是读237。
因此,高速缓存的操作被设计成在高速缓存中保持主内存的连续部分。你的
你的
|
2
3
C使用行主顺序存储多维数组,如中所述 § 6.5.2.1 Array subscripting, paragraph 3 C标准:
强调我的。 这是一张图片 Wikipedia 与其他存储多维数组的方法相比,它演示了这种存储技术, 列主要顺序 :
第一个函数,
|
3
1
在具有数据缓存的机器上(即使68030有一个),在连续的内存位置读/写数据要快得多,因为一个内存块(大小取决于处理器)从内存中提取一次,然后从缓存中调用(读操作)或一次全部写入(缓存刷新用于写操作)。 通过“跳过”数据(与以前的读取相差很远),CPU必须再次读取内存。 这就是为什么你的第一个片段更快。 对于更复杂的操作(例如快速傅立叶变换),如果数据被多次读取(与您的示例不同),许多库(例如fftw)建议使用 步幅 以适应您的数据组织(行/列)。 从未 使用它,总是先转置你的数据,使用1的步幅,它会比尝试不转置更快。 为了确保数据是连续的,不要使用二维符号。首先将数据定位在所选行中,并设置指向行开头的指针,然后在该行上使用内部循环。
如果您不能这样做,这意味着您的数据定向错误。 |
4
0
这是缓存的问题。 缓存将自动读取您请求的数据之后的数据。因此,如果您逐行读取数据,您请求的下一个数据将已经在缓存中。 |
5
0
在内存中,矩阵是线性对齐的,这样一行中的项在内存中彼此相邻。(
当您以另一种方式交叉它们时,它加载到内存中靠近它的其他值将不会是下一个读取的值,因此最终会出现更多的缓存未命中,因此当数据从内存层次结构的下一层引入时,CPU必须坐着等待。
当您回退到以前缓存的另一个条目时,它很可能已经从缓存中引导出来,而倾向于您自加载以来所使用的所有其他数据,因为它最近将不再被使用。(
|
Community wiki · C中有哪些耗时的操作? 1 年前 |
Community wiki · 将所有处理器电源都投入到任务中 1 年前 |
Community wiki · C++为C添加了什么?[已关闭] 1 年前 |
Community wiki · 打印1到1000,不带循环或条件 1 年前 |