LINUX.ORG.RU

Как измерить время выполнения программы в тиках, не меняя её?

 ,


0

1

Здравствуйте! Мне нужно измерить время выполнения программы для очень критической по времени среде. Но сами измерения выполняются на более мощном тестовом стенде.

Сперва я подумал на linux-утилиту time, что было бы идеально, если бы она показывала время в тиках, но она показывает время в секундах с точностью до тысячных, а поскольку на тестовом стенде процессор в несколько ГГц, даже изменение в несколько тысяч тиков будет сложно отследить таким образом.

Тогда я подумал, что можно было бы отредактировать программу, чтобы изменить точку входа на обёрточную функцию, которая сама вызовет main и зафиксирует точное время в тиках до и после выполнения main. Но с этим есть пару проблем: так не получится рассчитать время инициализации глобальных переменных и объектов классов; я не знаю, как отделить время user и sys от real (всё же на тестовом стенде много процессов); да и не факт, что компилятор что-то не переделает по другому при наличии доп. кода и другой точки входа, что повлияет на время выполнения.

Кто-нибудь знает, как замерять время в тиках?

Сорри за оффтоп: я как-то выполнил программу, не важно какую, делал её дома на Пне-100, а запускал на Пне-200, так скорость исполнения была настолько шустрой, что не успевал зафиксировать результат. 😁

Пришлось внести изменения в код.

sparkie ★★★★★
()

time использует times() которая возвращает данные о времени проведённом в sys/user как раз в тиках. Добавь в форматы time свой, который будет выводить тебе время в тиках - сырцы же есть.

Stanson ★★★★★
()

Я обрамлял исследуемый на быстродействие кусок кода ассемблерными вставками с инструкцией rtdsc.

Но это на часть кода, как на всю программу - хз.

Chord ★★★★
()

Сам попытался придумать, но не смог, нашёл это

Чуть подправил

/*
 * Hook main() using LD_PRELOAD, because why not?
 * Obviously, this code is not portable. Use at your own risk.
 *
 * Compile using 'gcc hax.c -o hax.so -fPIC -shared -ldl'
 * Then run your program as 'LD_PRELOAD=$PWD/hax.so ./a.out'
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <dlfcn.h>
#include <time.h>

/* Trampoline for the real main() */
static int (*main_orig)(int, char **, char **);

/* Our fake main() that gets called by __libc_start_main() */
int main_hook(int argc, char **argv, char **envp)
{
    clock_t c_run = clock();
    printf("--- Start Clock: %ld ---\n",c_run);
    int ret = main_orig(argc, argv, envp);
    clock_t c_end = clock();
    printf("----- End Clock: %ld----\n",c_end);

    printf("----- Clocks per external main: %ld----\n",c_end-c_run);
    return ret;
}

/*
 * Wrapper for __libc_start_main() that replaces the real main
 * function with our hooked version.
 */
int __libc_start_main(
    int (*main)(int, char **, char **),
    int argc,
    char **argv,
    int (*init)(int, char **, char **),
    void (*fini)(void),
    void (*rtld_fini)(void),
    void *stack_end)
{
    /* Save the real main function address */
    main_orig = main;

    /* Find the real __libc_start_main()... */
    typeof(&__libc_start_main) orig = dlsym(RTLD_NEXT, "__libc_start_main");

    /* ... and call it with our custom main function */
    return orig(main_hook, argc, argv, init, fini, rtld_fini, stack_end);
}

Собираем и дёргаем любые программы

gcc hook.c -o hook.so -fPIC -shared -ldl
dron@gnu:~/Рабочий-стол$ export LD_PRELOAD=`pwd`/hook.so 
dron@gnu:~/Рабочий-стол$ ls
--- Start Clock: 1690 ---
app  applib.out  ext.c  ext.so  hook.c  hook.so  main.c
----- End Clock: 2135----
----- Clocks per external main: 445----
dron@gnu:~/Рабочий-стол$ lua -e "('aaa'):rep(100):rep(1000)"
--- Start Clock: 4178 ---
----- End Clock: 6252----
----- Clocks per external main: 2074----
dron@gnu:~/Рабочий-стол$ uname 
--- Start Clock: 2873 ---
Linux
----- End Clock: 3209----
----- Clocks per external main: 336----
dron@gnu:~/Рабочий-стол$

Тока оно это, я не уверен что тут всё адекватно :D

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2)

«Тик» это что? Этим словом много разных вещей могут называть. В общем случае это просто какая-то удобная в данный момент единица времени. Чаще всего ей миллисекунды называют. Если тебе нужны такты процессора - так и пиши «такты процессора».

В любом случае, если у тебя критическая ко времени среда, то лучше избавиться от запуска программ вообще и сложить весь код в один бинарник, который запускается один раз при запуске системы и работает непрерывно. Тогда и «расходов на инициализацию переменных» не будет, а так же других расходов внутри ОС, которые очень сложно контролировать.

firkax ★★★★★
()

rdtsc/rdtscp вам в помощь, если речь об x86. Но в целом, похоже, эксперимент по измерению удава попугаями. Про прерывания/многозадачность уже упоминали, про кэш память, (не)предсказания ветвлений и динамическую тактовую частоту вы и сами наверняка в курсе.

Мне видится более практичным задание какой-то целевой планки по реакции/скорости и тестирование на её достижение при разных условиях работы.

opcode
()
Ответ на: комментарий от firkax

«Тик» это что?

Это десятитысячная миллисекунды:

$ ls /var/               
cache  db  empty  games  lib  local  lock  log	mail  named  opt  run  spool  tmp

$ (history -c 1).Duration

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 8
Ticks             : 89879
TotalDays         : 1,0402662037037E-07
TotalHours        : 2,49663888888889E-06
TotalMinutes      : 0,000149798333333333
TotalSeconds      : 0,0089879
TotalMilliseconds : 8,9879

dmitry237 ★★★★★
()
Ответ на: комментарий от dmitry237

Ну это какая-то твоя прога так считает, а у него может быть другой тик. Я же написал что их все как хотят понимают.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)

даже изменение в несколько тысяч тиков будет сложно отследить таким образом

Более того, оно не будет иметь никакого значения

buddhist ★★★★★
()

А как будет использоваться результат измерений? Мне кажется, что нужно прояснить решаемую задачу, для чего это, какая точность нужна. Пока предлагаемое решение выглядит как «так делать не нужно»; а вот как нужно - непонятно, т.к. неясно чего добиваемся.

blex ★★★★
()

Если подумать и применить индуктивную логику.

То можно провести серию экспериментов, на разных (специально подобранных) машинах.

Потом найти «закон» по которому можно предсказать, что эта данная программа с вероятностью в Н выполнится на искомой машине М раз из К запушенных.

Собственно это все.

alnkapa
()
Последнее исправление: alnkapa (всего исправлений: 1)

Какой-то странный эксперимент. Время зависит от многих факторов, даже от того, какой размер кешей в твоем процессоре, и как легли данные, как там распорядился предсказатель переходов, а он везде разный. Очень все странно и непонятно звучит

anonymous
()