2013-08-22 12 views
7

secondo il documento, http://gperftools.googlecode.com/svn/trunk/doc/cpuprofile.html, i profili di CPU non supporta più processi e genereranno file di output indipendente:gperftools cpu profiler non supporta il multi processo?

Se la forcella del programma, i bambini potranno anche essere profilati (in quanto ereditano la stessa impostazione CPUPROFILE) . Ogni processo è profilato separatamente ; per distinguere i profili figlio dal profilo principale e vicendevolmente, a tutti i bambini verrà aggiunto il proprio ID di processo nel nome CPUPROFILE.

ma quando provo come segue:

// 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; 
} 

// makefile

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 [email protected] $^ -L./ -L$(GPerfTools)/lib -Wl,-Bdynamic -lprofiler -lunwind 

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

// shell di comando

$ 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. 
$ 

Sembrerebbe che gperf non supporti il ​​multi processo, qualcuno potrebbe spiegarlo per favore? Grazie!

risposta

3

abbastanza vecchio, non so se hai trovato una risposta o no, ma ...

Sembra che ogni filo/forcella deve registrarsi utilizzando ProfilerRegisterThread(); È possibile trovare ulteriori informazioni in questi due numeri: Here e Here.

Anche qui è un codice di esempio, simile al tuo caso di test in cui le forche possono essere registered.

+0

Grazie per la risposta. Puoi aggiungere alcuni esempi di codice? – osgx

0

Attualmente sto usando gperftools per profilare un programma mpi e ho trovato questo problema. Dopo aver cercato su Google, trovo che ProfilerStart(_YOUR_PROF_FILE_NAME_) e ProfilerStop() devono essere richiamati durante l'esecuzione di ogni processo secondario e che _YOUR_PRO_FILE_NAME_ deve essere diverso tra diversi processi. Quindi è possibile eseguire le analisi di ogni processo.

collegamento (chiesto anche da ZRJ):
https://groups.google.com/forum/#!topic/google-perftools/bmysZILR4ik

Problemi correlati