【问题标题】:gperftools cpu profiler does not support multi process?gperftools cpu profiler 不支持多进程?
【发布时间】:2013-08-22 15:27:34
【问题描述】:

根据文档http://gperftools.googlecode.com/svn/trunk/doc/cpuprofile.html,cpu配置文件确实支持多进程并且会生成独立的输出文件:

如果您的程序分叉,孩子也将被分析(因为他们 继承相同的 CPUPROFILE 设置)。每个过程都被剖析 分别地;区分子配置文件和父配置文件 并且彼此之间,所有孩子都将附加他们的 process-id 到 CPUPROFILE 名称。

但是当我尝试如下:

// main_cmd_argv.cpp

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <gperftools/profiler.h>

int loop(int n) {
    int sum = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            sum = i + j;
            if (sum %3 == 0) {
                sum /= 3;
            }
        }
    }
    return 0;
}

int main(int argc, char* argv[]) {

    printf("%s\n%s\n", getenv("CPUPROFILE"), getenv("CPUPROFILESIGNAL"));

    if (argc > 1 && strcmp(argv[1], "-s")==0) {
        // single process
        loop(100000);
        printf("stoped\n");
    } else if (argc > 1 && strcmp(argv[1], "-m")==0) {
        // multi process
        pid_t pid = fork();
        if (pid < 0) {
            printf("fork error\n");
            return -1;
        }
        if (pid == 0) {    
            loop(100000);
            printf("child stoped\n");
        } else if (pid > 0) {
            loop(10000);
            printf("father stoped\n");
            wait(NULL);
        }        
    }   

    return 0;
}

// 生成文件

GPerfTools=/home/adenzhang/tools/gperftools

CCFLAGS=-fno-omit-frame-pointer -g -Wall

ALL_BINS=main_cmd_argv
all:$(ALL_BINS)

main_cmd_argv:main_cmd_argv.o
    g++ $(CCFLAGS) -o $@ $^ -L./ -L$(GPerfTools)/lib -Wl,-Bdynamic -lprofiler -lunwind

.cpp.o:
    g++ $(CCFLAGS) -c -I./ -I$(GPerfTools)/include -fPIC -o $@ $<
clean:
    rm -f $(ALL_BINS) *.o *.prof

// 外壳命令

$ make
g++ -fno-omit-frame-pointer -g -Wall -c -I./ -I/home/adenzhang/tools/gperftools/include -fPIC -o main_cmd_argv.o main_cmd_argv.cpp
g++ -fno-omit-frame-pointer -g -Wall -o main_cmd_argv main_cmd_argv.o -L./ -L/home/adenzhang/tools/gperftools/lib -Wl,-Bdynamic -lprofiler -lunwind
$ env CPUPROFILE=main_cmd_argv.prof ./main_cmd_argv -s
젩n_cmd_argv.prof
(null)
stoped
PROFILE: interrupts/evictions/bytes = 6686/3564/228416
$ /home/adenzhang/tools/gperftools/bin/pprof --text ./main_cmd_argv ./main_cmd_argv.prof 
Using local file ./main_cmd_argv.
Using local file ./main_cmd_argv.prof.
Removing killpg from all stack traces.
Total: 6686 samples
    6686 100.0% 100.0%     6686 100.0% loop
       0   0.0% 100.0%     6686 100.0% __libc_start_main
       0   0.0% 100.0%     6686 100.0% _start
       0   0.0% 100.0%     6686 100.0% main
$ rm main_cmd_argv.prof 
$ env CPUPROFILE=main_cmd_argv.prof ./main_cmd_argv -m
젩n_cmd_argv.prof
(null)
father stoped
child stoped
PROFILE: interrupts/evictions/bytes = 0/0/64
PROFILE: interrupts/evictions/bytes = 68/36/2624
$ ls 
main_cmd_argv  main_cmd_argv.cpp  main_cmd_argv.o  main_cmd_argv.prof  Makefile
$ /home/adenzhang/tools/gperftools/bin/pprof --text ./main_cmd_argv ./main_cmd_argv.prof 
Using local file ./main_cmd_argv.
Using local file ./main_cmd_argv.prof.
$

gperf 似乎不支持多进程,谁能解释一下?谢谢!

【问题讨论】:

    标签: linux profiling google-perftools gperftools


    【解决方案1】:

    相当老了,不知道你有没有找到答案,但是……

    似乎每个线程/分支都应该使用 ProfilerRegisterThread(); 您可以在这两个问题中找到更多信息:HereHere

    这里还有一个示例代码,类似于您的测试用例,其中分支可以是registered

    【讨论】:

    • 感谢您的回答。你能在其中添加一些代码示例吗?
    【解决方案2】:

    我目前正在使用gperftools 来分析 mpi 程序并遇到此问题。谷歌搜索后,我发现ProfilerStart(_YOUR_PROF_FILE_NAME_)ProfilerStop() 应该在每个子进程执行期间调用,并且_YOUR_PRO_FILE_NAME_ 在不同进程之间必须不同。然后您可以分析每个流程的性能。

    链接(ZRJ也问):
    https://groups.google.com/forum/#!topic/google-perftools/bmysZILR4ik

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-17
      • 2014-07-28
      • 2017-03-25
      相关资源
      最近更新 更多