valgrind, таймер профилирования истек?

Я пытаюсь профилировать простую прогу 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 ответа

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

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

Если вы действительно пытаетесь выяснить, куда уходит время, вы можете попробовать сделать это. Я поместил бесконечный цикл вокруг вашего кода и взял 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 приблизительно. Конечно, есть и другие способы ускорить этот код, например, исключив внутренний цикл, если вы действительно пытаетесь вычислить факториал.

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

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

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

Другие вопросы по тегам