我想分析一些C代码,但最直观的代价高的函数之一没有显示在GProf输出中。从GProf输出缺少函数
int main() {
initialise...
haloSwap();
for(...) {
functions...
propagate();
functions...
}
}
void propagate() {
for (x)
for (y)
for (z)
grid[xNew][yNew][zNew] = grid[x][y][z];
haloSwap();
}
void haloSwap() {
// Horizontal swap
create buffers...
MPI_Sendrecv(buffers);
recreate grid from buffers...
// Vertical swap
create buffers...
MPI_Sendrecv(buffers);
recreate grid from buffers...
}
希望伪代码可以通过某种方式来解释设置。 haloSwap()
涉及线程之间的大量通信,我觉得这是算法的昂贵部分。它在初始化过程中被调用,然后在算法的循环过程中被重复调用。
即使我知道它从propagate()
内部被称为1000+次,GProf只显示1个呼叫到haloSwap
(初始化期间)。
propagate()
显示为代码中最昂贵的部分,但我想知道它是xyz循环还是MPI comminucation。
有没有人知道为什么从propagate
呼叫haloSwap
似乎忽略了呼叫数量和功能花费的时间?
haloSwap
被另一个.c文件内定义的,这可能是一个因素?
如果我在呼叫propagate
(而不是内部呼叫)后将haloSwap
的呼叫移动到主循环,GProf仍然只显示1个呼叫。
您可能正在使用optimisations进行编译,而'propagate()'最终被内联。告诉你的编译器不要内联函数。例如,对于GCC,选项是“-fno-inline”。 –
添加到@Hristo_Iliev评论。 mpicc(来自MPICH)包装器使用包含-finline-small-functions标志的-O2优化。如果您想要从任何优化中排除函数,请在函数上使用gcc属性,例如 void haloSwap()__attribute __(optimize(“ - O0”)) – Angelos
如果您正在使用MPI,那么它正在执行I/O ,并且gprof众所周知是盲目的,因为采样在I/O期间暂停。你可能花99%的时间在I/O上,但gprof不会显示它。任何称自己为“CPU分析器”的东西都是如此。 –