valgrind, таймер профилирования истек? - PullRequest
10 голосов
/ 27 января 2010

Я пытаюсь профилировать простую прогу c, используя valgrind:

[zsun @ nel6005001 ~] $ valgrind --tool = memcheck ./fl.out== 2238 == Memcheck, детектор ошибок памяти== 2238 == Copyright (C) 2002-2009 и GNU GPL'd, Джулиан Сьюард и соавт.== 2238 == Использование Valgrind-3.5.0 и LibVEX;перезапустить с -h для получения информации об авторских правах== 2238 == Команда: ./fl.out== 2238 ==== 2238 ==== 2238 == РЕЗЮМЕ КАРТЫ:== 2238 == используется на выходе: 1168 байт в 1 блоках== 2238 == общее использование кучи: 1 выделяет, 0 освобождает, выделено 1168 байт== 2238 ==== 2238 == РЕЗЮМЕ УТЕЧКИ:== 2238 == определенно потеряно: 0 байтов в 0 блоках== 2238 == косвенно потеряно: 0 байтов в 0 блоках== 2238 == возможно потеряно: 0 байтов в 0 блоках== 2238 == все еще достижимо: 1168 байт в 1 блоках== 2238 == подавлено: 0 байтов в 0 блоках== 2238 == Перезапустите с --leak-check = full, чтобы увидеть детали утечки памяти== 2238 ==== 2238 == Для подсчета обнаруженных и подавленных ошибок, перезапустите с: -v== 2238 == РЕЗЮМЕ ОШИБОК: 0 ошибок из 0 контекстов (исключено: 12 из 8)Таймер профилирования истек

Код c, который я пытаюсь профилировать, выглядит следующим образом:

void forloop(void){
    int fac=1;
    int count=5;
    int i,k;

    for (i = 1; i <= count; i++){
        for(k=1;k<=count;k++){
            fac = fac * i;
        }
    }
}

Появляется «Таймер профилирования истек», что это значит?Как решить эту проблему?ТНХ!

Ответы [ 3 ]

18 голосов
/ 27 января 2010

Проблема в том, что вы используете valgrind в программе, скомпилированной с -pg. Вы не можете использовать valgrind и gprof вместе. Руководство по valgrind предлагает использовать OProfile, если вы работаете в Linux и вам необходимо профилировать фактическую эмуляцию программы в valgrind.

1 голос
/ 03 февраля 2010

Кстати, это не компьютерный факториал.

Если вы действительно пытаетесь узнать, куда уходит время, вы можете попробовать stackshots . Я поместил бесконечный цикл вокруг вашего кода и взял 10 из них. Вот код:

 6: void forloop(void){ 
 7:   int fac=1; 
 8:   int count=5; 
 9:   int i,k; 
10:
11:   for (i = 1; i <= count; i++){ 
12:       for(k=1;k<=count;k++){ 
13:           fac = fac * i; 
14:       } 
15:   } 
16: } 
17:
18: int main(int argc, char* argv[])
19: {
20: int i;
21: for (;;){
22:     forloop();
23: }
24: return 0;
25: }

А вот стеки, переупорядоченные с самыми частыми наверху:

forloop() line 12
main() line 23

forloop() line 12 + 21 bytes
main() line 23

forloop() line 12 + 21 bytes
main() line 23

forloop() line 12 + 9 bytes
main() line 23

forloop() line 13 + 7 bytes
main() line 23

forloop() line 13 + 3 bytes
main() line 23

forloop() line 6 + 22 bytes
main() line 23

forloop() line 14
main() line 23

forloop() line 7
main() line 23

forloop() line 11 + 9 bytes
main() line 23

Что это говорит вам? В нем говорится, что строка 12 потребляет около 40% времени, а строка 13 - около 20% времени. Также сообщается, что строка 23 потребляет почти 100% времени.

Это означает, что развертывание цикла в строке 12 потенциально может дать вам коэффициент ускорения 100 / (100-40) = 100/60 = 1,67x приблизительно. Конечно, есть и другие способы ускорить этот код, например, исключив внутренний цикл, если вы действительно пытаетесь вычислить факториал.

Я просто указываю на это, потому что это простой способ профилирования.

0 голосов
/ 27 января 2010

Вы не сможете вычислить 10000! таким образом. Вам понадобится какая-то bignum реализация для вычисления факториалов. Это потому, что int имеет длину «обычно» 4 байта, что означает, что «обычно» он может содержать 2^32 - 1 (подписано int, 2^31) - 13! больше, чем это. Даже если вы используете unsigned long («обычно» 8 байт), вы переполнитесь к тому моменту, когда достигнете 21!.

Что касается того, что означает «таймер профилирования истек» - это означает, что valgrind получил сигнал SIGPROF: http://en.wikipedia.org/wiki/SIGPROF (возможно, это означает, что ваша программа заняла слишком много времени).

...