2

さて、私は数学的演算を実行するための C コードをいくつか手に入れました。ハードウェアタイマー割り込みなどを使用して、操作の状態、つまり現在の反復を分析できるn秒ごとに呼び出される何らかのメソッドを登録する方法があるかどうか疑問に思っていましたか?

私がこれを尋ねる理由は、これを実装する一般的な方法は、変数で現在の反復を追跡することだと知っているからです。たとえば、整数が呼び出さprogressれ、コードに次のような IF ステートメントが含まれているとします。

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

しかし、mod操作の実行には比較的長い時間がかかると信じているため、最適化の観点から、何度も何度も実行されるループ内にそれを置くという考えは私を怖がらせます.

そのため、進行状況の出力を外部に通知する方法があると、素晴らしく効率的であると感じています。これを実行するための優れた方法はありますか、それとも単純な「mod チェック」が (最適化の点で) 最適ですか?

4

5 に答える 5

5

私は mod チェックを使用しますが、代わりに減算を使用する可能性があります :-)

icount = 0;
progress = 10000;
/* ... */
    if (--progress == 0) {
        progress = 10000;
        printf("Currently at iteration %d0000\n", ++icount);
    }
/* ... */
于 2010-10-04T15:55:40.363 に答える
1

mod操作は通常遅いですが、コンパイラはこれを非常にうまく最適化して予測できるはずであり、10,000のifを1回だけ誤予測し、1つのmod操作と約20サイクル(誤予測の場合)を焼き付けます。結構です。したがって、10,000 回の反復ごとに 1 つの mod 操作を最適化しようとしています。もちろん、これは、仕様が不明な組み込みシステムではなく、最新の一般的な CPU で実行していることを前提としています。これは、カウンター変数を使用するよりも高速です。提案: タイミング コードを使用する場合と使用しない場合でテストし、実際に問題がある場合は複雑な解決策を見つけてください。

時期尚早の最適化は諸悪の根源です。-クヌート

于 2010-10-04T15:53:03.847 に答える
1

mod は除算とほぼ同じ速度です。最近のほとんどの CPU では、これは約 5 ~ 10 サイクルを意味します。言い換えれば、乗算/加算/減算よりも遅くはありませんが、心配するほどではありません。

ただし、別のスレッドまたはそのようなもので作業を行っている場合は、ループの回転で刺すことを避けたいと思うのは正しいことですtimer_create()timerfd_create()

ただし、シングルスレッドの場合は、それを入れるだけで十分です。

于 2010-10-04T15:57:25.547 に答える
1

一定間隔で信号を発生させるために使用します。alarm setitimerSIGALRM

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変数を介して行います。

于 2010-10-04T16:05:36.527 に答える
0

外部スレッドから監視できる反復用のグローバル変数を持つことができます。

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

ただし、データ競合に注意する必要があるかもしれません。

于 2010-10-04T15:55:46.770 に答える