我从与 OpenMP 并行的应用程序中得到了错误的数值结果。每个 OpenMP 线程在 NVIDIA GPU 上运行一个或多个流。我怀疑更新内存时 OpenMP 线程或 CUDA 流之间存在竞争条件。
我们如何找出访问相同主内存地址范围的 OpenMP 线程/CUDA 流集?有什么工具吗?
最佳答案
在 CPU 上,您可以使用编译器的线程清理程序。 GCC 和 Clang 通过选项 -fsanitize=thread
支持这一点。您可以在 LLVM documentation 中找到更多信息。 。请注意,这些工具相当新,因此可能还处于实验阶段。或者,Helgrind Valgrind 可以帮助您找到经常导致竞争条件的同步问题。如果您与 LLVM 密切相关,您可以尝试 Archer 。还有一些非免费工具(包括 Intel Inspector 或 Coderrect)主要基于过去十年对该主题的积极公共(public)研究(例如,请参阅 here)。
在具有 CUDA 功能的 GPU 上,我所知道的唯一简单/即用的工具是 CUDA-MemCheck这与 Valgrind 在 CPU 上提供的类似。它可以与 CUDA-GDB 结合使用非常容易地发现小型 CUDA 代码中的错误。
最后,当您面临重现性问题(例如竞争条件)时,确定性反向调试器确实可以发挥作用。 RR是一个很棒的开源工具。我不太确定它支持运行 CUDA 内核的应用程序,但它确实值得一试。请注意,RR 倾向于按顺序运行线程(尽管它们被抢占),从而影响结果行为。
关于debugging - 检测 OpenMP 线程/CUDA 流之间的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67074712/