【问题标题】:Need help understanding kcachegrind需要帮助了解 kcachegrind
【发布时间】: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


【解决方案1】:

那里似乎没有太多信息,例如,在左侧窗口中,“Self”是什么,“incl.”是什么?

令人惊讶的是,这是kcachegrind FAQ 中的第一个常见问题。具体来说,来自该链接:

...区分函数本身的成本('Self Cost')和包括所有调用函数的成本('Inclusive Cost' [incl.])是有意义的

现在,您没有显示任何代码,甚至没有提示您的程序做了什么,但是...

据我所知,1 核和 16 核的数据丢失数量相同...

如果您有一些固定数量的数据要处理,并且它在缓存之外开始,则需要相同数量的未命中来覆盖它是合理的。

您也没有提供有关您的硬件平台的任何线索,所以我不知道您是否在单个插槽上有 16 个内核并具有统一的最后一级缓存,或者 4x4 并且您的最后一级缓存未命中被划分为那些插座,或者什么。

但我仍然无法弄清楚为什么在一个核心上,执行时间是 0.62 秒,而在 16 个核心上,执行时间接近 1 秒

也许是同步成本。也许它是在 valgrind 下运行的神器。也许是别的东西。如果没有关于代码的任何信息,也许没有人可以真正帮助分析您的代码。

如果有人能告诉我在 kcachegrind 中寻找什么...

你想找到什么?你的代码在做什么?当不在 valgrind 下运行时,那个时差仍然存在吗?您使用什么库,什么操作系统,什么硬件平台?

【讨论】:

  • 不使用valgrind时有时间差。使用 valgrind 时,时间差几乎消失了。我只是想找出 1 核和 16 核之间的区别 - 具体来说,为什么在 16 核上运行我的代码会导致执行时间增加 40%。
  • 忘了说,没有调用 MPI 也没有同步。
猜你喜欢
  • 2017-06-19
  • 1970-01-01
  • 2021-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
相关资源
最近更新 更多