開発ボード(ZC702)でZynqチップを使用しています。これは667MHzのデュアルcortex-A9 MPCoreを備え、Linuxカーネル3.3が付属しています。プログラムの実行時間を比較したかったので、最初にclock_gettimeを使用し、次にARMのコプロセッサによって提供されるカウンタ。カウンタは、1プロセッササイクルごとに増分します。(stackoverflowとこれに関するこの質問に基づく)
-O0フラグを使用してプログラムをコンパイルします(並べ替えや最適化を実行したくないため)
パフォーマンスカウンターで測定する時間は、583833498(サイクル)/ 666.666687 MHz = 875750.221(マイクロ秒)です。
clock_gettime()(REALTIMEまたはMONOTONICまたはMONOTONIC_RAWのいずれか)を使用している場合、測定される時間は 731627.126(マイクロ秒)で、150000マイクロ秒少なくなります。
なぜこれが起こっているのか誰かが私に説明できますか?なぜ違いがあるのですか?プロセッサはクロックスケールしませんが、clock_gettimeで測定される実行時間を短縮するにはどうすればよいですか?以下にサンプルコードがあります。
#define RUNS 50000000
#define BENCHMARK(val) \
__asm__ __volatile__("mov r4, %1\n\t" \
"mov r5, #0\n\t" \
"1:\n\t"\
"add r5,r5,r4\n\t"\
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"mov r4 ,r4 \n\t" \
"sub r4,r4,#1\n\t" \
"cmp r4, #0\n\t" \
"bne 1b\n\t" \
"mov %0 ,r5 \n\t" \
:"=r" (val) \
: "r" (RUNS) \
: "r4","r5" \
);
clock_gettime(CLOCK_MONOTONIC_RAW,&start);
__asm__ __volatile__ ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(start_cycles));
for(index=0;index<5;index++)
{
BENCHMARK(i);
}
__asm__ __volatile__ ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(end_cycles));
clock_gettime(CLOCK_MONOTONIC_RAW,&stop);