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 (вероятно, это означает, что ваша программа заняла слишком много времени).