为什么迭代二维数组行优先比列优先更快?

2023-12-29

下面是简单的 C++ 代码,用于比较迭代二维数组行主要与列主要。

#include <iostream>
#include <ctime>

using namespace std;

const int d = 10000;

int** A = new int* [d];

int main(int argc, const char * argv[]) {
    for(int i = 0; i < d; ++i)
        A[i] = new int [d];
    
    clock_t ColMajor = clock();
    
    for(int b = 0; b < d; ++b)
        for(int a = 0; a < d; ++a)
            A[a][b]++;
    
    double col = static_cast<double>(clock() - ColMajor) / CLOCKS_PER_SEC;
    
    clock_t RowMajor = clock();
    for(int a = 0; a < d; ++a)
        for(int b = 0; b < d; ++b)
            A[a][b]++;
    
    double row = static_cast<double>(clock() - RowMajor) / CLOCKS_PER_SEC;
    

    
    cout << "Row Major : " << row;
    cout << "\nColumn Major : " << col;

    return 0;
}

不同值的结果d:

d = 10^3 :

行专业:0.002431

列专业:0.017186

d = 10^4 :

行专业:0.237995

列专业:2.04471

d = 10^5

行专业:53.9561

栏目专业:444.339

现在的问题是为什么行专业比列专业更快?


这显然取决于您所使用的机器,但一般来说:

  1. 您的计算机将部分程序内存存储在缓存中,该缓存的延迟比主内存小得多(即使在补偿缓存命中时间时也是如此)。

  2. C 数组按行主顺序连续存储。这意味着如果您要求元素x,然后元素x+1存储在主存储器中紧随其后的位置x被储存了。

  3. 计算机缓存通常会“抢先”使用尚未使用但本地接近程序已使用的内存的内存地址填充缓存。想象一下你的计算机在说:“好吧,你想要地址 X 处的内存,所以我假设你很快就会想要 X+1 处的内存,因此我会抢先为你获取该内存并将其放入你的缓存中” 。

当您通过行主序枚举数组时,您是以连续方式存储在内存中的方式枚举它,并且您的机器已经为您预先将这些地址加载到缓存中because它猜你想要它。因此,您可以获得更高的缓存命中率。当您以另一种非连续方式枚举数组时,您的机器可能无法预测您正在应用的内存访问模式,因此它无法为您预先将内存地址拉入缓存,并且您将无法不会产生那么多的缓存命中,因此必须更频繁地访问主内存,这比缓存慢。

另外,这可能更适合https://cs.stackexchange.com/ https://cs.stackexchange.com/因为系统缓存的行为方式是在硬件中实现的,空间局部性问题似乎更适合那里。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么迭代二维数组行优先比列优先更快? 的相关文章

随机推荐

  • VHDL-读取HEX文件

    In VHDL 从 HEX 文件初始化 std logic vector 数组 https stackoverflow com questions 20164216 vhdl init std logic vector array from
  • 为什么我们不应该在java中使用受保护的静态

    我正在经历这个问题Java中有没有办法覆盖类变量 https stackoverflow com questions 685300 is there a way to override class variables in java 首先c
  • ListView 项目上的删除按钮

    我开始为 UWP 进行开发 我正在尝试创建一个ListView填充有x bind 现在我想在所有单个项目上创建一个按钮来删除它们 类似于 Windows 10 邮件 我已经创建了
  • 使用字符串值作为变量名[重复]

    这个问题在这里已经有答案了 是否可以使用 String 作为变量名 就像这个例子一样 String musicPlaying music2 Music music1 new Music blaalla Music music2 new Mu
  • 在 Firebase 中构建关系

    我的 Firebase 中有两项 providers and services 我正在尝试找出使用 Firebase 推荐的扁平化架构方法构建和建立关系的最佳方法 我的数据看起来像这样 services hip replacement ti
  • 在java 8中是否可以做一个懒惰的groupby,返回一个流?

    我有一些较大的文本文件 我想通过对其行进行分组来处理它们 我尝试使用新的流媒体功能 例如 return FileUtils readLines parallelStream map collect groupingBy pair gt pa
  • 如何使用 exoplayer 横向全屏播放视频

    我正在使用 exoplayer 在我的 Android 应用程序中播放来自 url 的视频 在纵向中 一切都按预期工作 在活动中使用视图页面 片段和选项卡 我的目标是当用户处于横向状态时全屏播放视频 这意味着只有视频将以横向方式播放 所有其
  • 如何在解决方案中的所有项目之间共享 LocalDB 实例?

    我有一个 VS 2012 解决方案设置如下 EF 模型项目 EF模型测试项目 ASP NET MVC 4 应用程序 WCF数据服务项目 在开发过程中 我想使用 LocalDB 作为 EF 的后备数据库 MVC 和 WCF 项目都使用 EF
  • 将图像存储在 MySQL 数据库中

    我想知道如何在 MySQL 数据库中存储图像和文件 我想获得这样的图像和文件www example rsrc php example image jpg Facebook 上的示例 facebook example com rsrc php
  • 在 DataGridViewComboboxColumn 上设置所选项目

    我有一个带有 DataGridViewComboboxColumn 列的 datagridview 其中包含 3 个值 小号中号大号 我恢复了用户默认值 在本例中为 中 我想在 datagridview 中显示一个下拉单元格 但默认值为 中
  • spring.jmx.enabled 的确切目的是什么?

    对于 Spring Boot v2 4 2 在通过 JMX 进行监控和管理 https docs spring io spring boot docs current reference html production ready feat
  • 在 PSQL 脚本中使用环境变量

    是否可以在 sql 文件中使用 Linux 环境变量 我正在使用复制 选择查询写入输出文件 并且我想将该目录放入变量中 所以我想做一些类似的事情 COPY SELECT FROM a TO outputdir a csv Outputdir
  • 为动态创建的组件分离 vuex 存储

    这个问题让我有点卡住了 不幸的是 我在这里找不到答案 问也没有帮助 因此 在做了一些研究并到处询问之后 似乎我找到了这个问题的解决方案 如果您有一个已经知道答案的问题 并且您 希望公开记录这些知识 以便其他人 包括你自己 稍后可以找到它 当
  • 从字符串中提取版本号

    我有一个包含组件和版本号的字符串 data c kuh small1 divider bin 1 4 4 divider conf 1 3 3 w 1 16 storage bin 1 5 4 storage conf 1 5 0 w 1
  • 在 R 中,如何在对数据进行聚类后绘制相似度矩阵(如框图)?

    我想生成一个图表 显示聚类数据和相似度矩阵之间的相关性 我怎样才能在 R 中做到这一点 R 中是否有任何函数可以创建像此链接中的图片一样的图形 http bp0 blogger com VCI4AaOLs A SG5H jm f8I AAA
  • 列出 VBA 2003 中类的属性

    我到处搜索 看看这个问题是否有一个简单的答案 但似乎没有 我正在使用 Excel VBA 2003 是的 我知道它已经过时 但我无法更改它 我想要做的就是列出给定自定义类中所有可读属性的名称和值 我想做这样的事情 类定义 对于名为 cFoo
  • Nginx 尝试记录到 /var/logs 而不是 /var/log?

    我注意到当我使用以下命令测试我的 nginx 配置时nginx t 它给了我一个警告 nginx alert could not open error log file open var logs nginx error log faile
  • 主线程中的错误:MKNormalizedPointForLayer

    我正在开发基于核心位置的iPhone应用程序出现一些奇怪的错误 当我在后台状态发送应用程序并将其发送回前台时 在主线程中出现名为错误MKNormalizedPointForLayer仅此而已 我必须去哪里寻找解决方案 谷歌在这方面做得很差
  • JavaFX WebView 未加载 HTTPS 页面

    我使用 JavaFX WebView 控件编写了一个浏览器 一切都很好 直到我尝试加载加密页面 我尝试https www gmail com https www gmail com我在加载工作线程的异常属性中收到 未知错误 仅当我将应用程序
  • 为什么迭代二维数组行优先比列优先更快?

    下面是简单的 C 代码 用于比较迭代二维数组行主要与列主要 include