Использование аппаратного таймера в C - PullRequest
2 голосов
/ 04 октября 2010

Хорошо, у меня есть некоторый C-код для выполнения математической операции, которая может, в значительной степени, занять любое время (конечно, в зависимости от операндов, предоставленных ему). Мне было интересно, есть ли способ зарегистрировать какой-то метод, который будет вызываться каждые n секунд, который может анализировать состояние операции, то есть, на какой итерации она находится в данный момент, возможно, с использованием аппаратного прерывания таймера или что?

Причина, по которой я спрашиваю это, состоит в том, что я знаю, что общий способ реализации этого состоит в том, чтобы отслеживать текущую итерацию в переменной; скажем, целое число с именем progress и оператор IF в коде:

if ((progress % 10000) == 0)
    printf("Currently at iteration %d\n", progress);

но я считаю, что операция мода занимает относительно длительное время, поэтому идея ее выполнения внутри цикла, который будет выполняться много, много раз, пугает меня с точки зрения оптимизации.

Так что у меня возникает ощущение, что иметь внешний способ оповещения о прогрессе печати приятно и эффективно. Есть ли какие-нибудь отличные способы сделать это, или простая «проверка мод» лучше (с точки зрения оптимизации)?

Ответы [ 5 ]

4 голосов
/ 04 октября 2010

Я бы пошел с проверкой модов, но, возможно, вместо вычитаний: -)

icount = 0;
progress = 10000;
/* ... */
    if (--progress == 0) {
        progress = 10000;
        printf("Currently at iteration %d0000\n", ++icount);
    }
/* ... */
1 голос
/ 04 октября 2010

Используйте alarm setitimer для повышения SIGALRM сигналов через равные промежутки времени.

struct itimerval interval;

void handler( int x ) {
    write( STDOUT_FILENO, ".", 1 ); /* Defined in POSIX, not in C */
}

int main() {
    signal( SIGALRM, &handler );
    interval.it_value.tv_sec = 5; /* display after 5 seconds */
    interval.it_interval.tv_sec = 5; /* then display every 5 seconds */
    setitimer( ITIMER_REAL, &interval, NULL );

    /* do computations */

    interval.it_interval.tv_sec = 0; /* don't display progress any more */
    setitimer( ITIMER_REAL, &interval, NULL );
    printf( "\n" ); /* done with the dots! */
}

Обратите внимание, что для вызова внутри handler допустимо только несколько функций. Они перечислены частично вниз на этой странице . Если вы хотите сообщить что-нибудь для более красивой распечатки, сделайте это с помощью переменной sig_atomic_t.

1 голос
/ 04 октября 2010

мод примерно такой же скорости, как и деление, на большинстве процессоров в наши дни это означает около 5-10 циклов ... другими словами, вряд ли что-либо, медленнее, чем умножение / сложение / вычитание, но недостаточно для того, чтобы действительно беспокоиться.

Тем не менее, вы правы, что хотите избежать укуса в цикле, если вы выполняете работу в другом потоке или что-то в этом роде, если вы работаете в unixish системе, есть timer_create() или в linux, который намного проще в использовании. timerfd_create()

Но для однопоточных, просто вставьте его, если достаточно.

1 голос
/ 04 октября 2010

В то время как операции с модами обычно медленны, компилятор должен быть в состоянии оптимизировать и прогнозировать это действительно хорошо, и он может ошибочно предсказывать только один раз каждые 10 000 операций if, запись одной операции мода и ~ 20 циклов (для неправильного предсказания) это нормально. Таким образом, вы пытаетесь оптимизировать одну операцию мода каждые 10 000 итераций. Конечно, это предполагает, что вы используете его на современном типичном процессоре, а не на какой-то встроенной системе с неизвестными спецификациями. Это должно быть даже быстрее, чем наличие переменной счетчика. Предложение: Протестируйте его с кодом времени и без него и найдите сложное решение, если действительно существует проблема.

Преждевременная оптимизация - корень всего зла. -Knuth

0 голосов
/ 04 октября 2010

у вас может быть глобальная переменная для итераций, которую вы можете отслеживать из внешнего потока.

While () {
  Print(iteration);
  Sleep(1000);
}

Возможно, вам придется следить за гонками данных.

...