【发布时间】:2016-05-03 06:02:36
【问题描述】:
我正在尝试了解kcachegrind,那里似乎没有太多信息,例如,在左侧窗口中,“Self”是什么,“incl.”是什么? (见1 core)。
我做了一些弱扩展测试,没有通信,所以我猜这与缓存未命中有关。但据我所知,1 核和 16 核的数据丢失数量相同,请参阅:16 cores。
我看到的 1 核和 16 核之间的唯一区别是,在 16 核上调用 memcpy 的次数要少得多(我可以解释一下)。但我仍然无法弄清楚为什么在一个核心上,执行时间是 0.62 秒,而在 16 个核心上,执行时间更接近 1 秒。每个处理器都在做相同数量的工作。如果有人能告诉我要在 kcachegrind 中寻找什么,那就太棒了,这是我第一次使用 kcachegrind 和 valgrind。
编辑:我的代码以压缩行格式连接矩阵。它涉及循环子矩阵的条目并使用 memcpy 将值复制到结果矩阵中。 这是代码: - 我不能发布超过 2 个链接...所以我会在评论中发布。
我只在循环本身上启动了 valgrind,循环也是 0.62 秒执行时间和 1 秒执行时间之间的差异。花费最多时间的部分是对 memcpy 的调用(下面 github gist 中的第 37 行),当我将其注释掉时,我的代码执行时间不到 0.2 秒,尽管 1 到 16 个内核之间仍然有增加(大约增加 30%)。
我在一个 haswell 节点上运行我的代码,该节点由 24 个内核组成(两个英特尔® 至强® 处理器 E5-2690 v3)
每个核心有 5GB 内存。
【问题讨论】:
-
那看起来像单线程的代码是如何跨 16 个内核运行的?它只是一个线程在整个地方进行上下文切换,还是还有其他你没有展示的东西?
-
矩阵是自动分布的。因此,如果我获得 row_start,它只会获得位于该核心上的矩阵部分的 row_start。同样,如果我得到非零 (NNZ) 的数量,它只会返回该核心上条目的 NNZ。在这个算法中,不需要访问其他内核上的数据,因此它看起来是单线程的。但是,每个 memcpy 将根据它们所在的核心复制不同的数据。但是,如果我想访问驻留在另一个核心上的矩阵的一部分,那么我将不得不调用 MPI 调用。
标签: c++ valgrind call-graph callgrind kcachegrind