【问题标题】:Best strategy for profiling memory usage of my code (open source) and 3rd party code(closed source)分析我的代码(开源)和第 3 方代码(闭源)的内存使用情况的最佳策略
【发布时间】:2011-09-05 18:11:56
【问题描述】:

我很快将负责对用 C/C++ 编写并使用 CUDA 来利用 GPU 处理的代码进行适当的内存配置。

我最初的想法是创建宏和运算符重载,以便我在源代码中跟踪对 malloc、free、delete 和 new 的调用。我只能包含不同的标题,并使用__FILE__ and __LINE__ 宏将内存调用打印到日志文件。此类策略可在此处找到:http://www.almostinfinite.com/memtrack.html

在第 3 方库中的链接中跟踪该使用情况的最佳方法是什么?我假设我几乎只能在函数调用之前和之后跟踪内存使用情况,对吗?在我的宏/重载场景中,我可以简单地跟踪请求的大小来确定需要多少内存。我怎么能知道 3rd 方库正在使用多少?我的理解也是,跟踪“免费”并不能真正让您了解代码在任何特定时间使用了多少,因为它不一定会返回给操作系统。我感谢任何关于此事的讨论。

我真的不想使用任何内存分析工具,如 Totalview 或 valgrind, 因为它们通常会做很多其他事情(边界检查等),这似乎会使软件运行得非常慢。另一个原因是我希望这在某种程度上是线程安全的——我相信该软件使用 MPI 来产生进程。我将尝试实时对此进行分析,以便我可以转储到日志文件或其他进程可以读取的内容,以便在软件运行时可视化内存使用情况。这也将主要在 linux 环境中运行。

谢谢

【问题讨论】:

    标签: c++ memory-management profiling cuda


    【解决方案1】:

    也许链接器选项 --wrap=symbol 可以帮助你。真的很好的例子可以在这里找到: man ld

    【讨论】:

      【解决方案2】:

      也许valgrind 和 Massif 工具?

      【讨论】:

      • 特别提到我不打算使用重型分析工具。我希望能够在运行我的软件时运行它,而对性能的影响很小。
      【解决方案3】:

      为了在 Linux 上跟踪我的程序的实时内存消耗,我只需阅读 /proc/[pid]/stat。这是一个相当轻量级的操作,如果您要跟踪的第 3 方库执行后续工作,在您的情况下可以忽略不计。如果想在 3rd 方库工作时获得内存信息,可以将stat 文件读入独立线程或其他进程中。 (内存峰值很少在函数调用之前或之后追加!...)

      对于 CUDA/GPU,我认为 gDEBugger 可以帮助您。我不确定,但内存分析器对性能影响不大。

      【讨论】:

        【解决方案4】:

        您可以试试 Google 的 PerfTools 的堆分析器:

        http://google-perftools.googlecode.com/svn/trunk/doc/heapprofile.html

        它非常轻巧;它实际上取代了 malloc/calloc/realloc/free 来添加检测代码。它主要在 Linux 平台上进行测试。

        如果您使用调试符号进行编译,并且您的第三方库带有调试版本变体,那么 PerfTools 应该会做得很好。如果您没有调试符号库,无论如何都要使用调试符号构建代码。它会为你的代码提供详细的数字,所有剩余的都可以作为第三方库的属性。

        【讨论】:

          【解决方案5】:

          如果您不想使用“外部”工具,可以尝试使用以下工具:

          • mtrace

            它为 malloc、realloc 和 free 安装处理程序,并将每个操作记录到文件中。有关代码使用示例,请参阅我整理的 Wikipedia。

          • dmalloc

            这是一个您可以在代码中使用的库,它可以发现内存泄漏、错误和无效地址的使用。您也可以在编译时使用 -DDMALLOC_DISABLE 禁用它。

          无论如何,我宁愿不采用这种方法。相反,我建议您在 valgrind(或任何等效工具)下的测试服务器上运行应用程序时尝试对应用程序进行压力测试,并确保您正确进行内存分配,然后让应用程序在生产环境中运行而无需任何内存分配检查以最大化速度。但实际上,这取决于您的应用程序做什么以及您的需求是什么。

          【讨论】:

            【解决方案6】:

            您可以使用 Visual Studio 2010 Premium 和 Ultimate 中包含的分析器。

            它允许您在不同的性能测量方法之间进行选择,对您最有用的可能是 CPU 采样,因为它会以任意时间间隔冻结您的程序并确定当前正在执行的函数,从而不会使您的程序大量运行慢一点。

            【讨论】:

            • 已编辑问题以反映我可能不会像 linux 那样在 windows 中运行它
            【解决方案7】:

            我相信这个问题有两个非常不同的答案。一个用于 C/C++ 领域。 CUDA 领域还有一秒。

            在 CPU 上:

            我已经为 new 和 delete 编写了自己的替换。他们非常缓慢,并没有太大帮助。我用过全视图。我喜欢用于 OpenMP 调试的 totalview,但我同意用于内存调试的速度非常慢。我从未尝试过valgrind。我听说过类似的事情。

            我遇到的唯一值得一提的内存调试工具是Intel Parallel Inspector's Memory Checker。 注意:因为我是学生,所以我能够以便宜的价格获得教育许可证。也就是说,这太棒了。我花了 12 分钟才发现隐藏在 50 万行代码中的内存泄漏——我没有释放我捕获并忽略的抛出的错误对象。我非常喜欢这个软件,以至于当我的 raid 失败/Win 7 吃掉了我的电脑(同时考虑自动更新和 raid 重建)时,我停止了一切并重建了电脑,因为我知道重建双启动需要更少的时间(48 小时) 而不是以另一种方式找到内存泄漏。 如果你不相信我的古怪说法,download an evaluation version。

            在 GPU 上:

            我认为你运气不好。对于 CUDA 中的所有内存问题,我基本上不得不在 cudaMalloc 等周围开发自己的工具和包装器。这并不漂亮。 nSight 确实给你买了一些东西,但在这一点上,除了“这里是你现在分配了多少”之外,并没有太多。在那个悲伤的地方,几乎我在 CUDA 上遇到的每一个性能问题都直接取决于我的内存访问模式(那个或我的线程块大小)。

            【讨论】:

            • 至于第三者,我觉得这很敏感。我没有很多经验——前段时间确实弄乱了一个 FPGA 库——但我基本上还是被困在编写自己的包装器中,效率很低(在编码时间和调试/分析方面)。
            猜你喜欢
            • 2010-09-12
            • 1970-01-01
            • 2013-09-17
            • 2015-11-15
            • 2011-02-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多