セマフォの取得に必要なクロック サイクル数を測定するための C コードを作成しています。私は rdtsc を使用しています。セマフォで測定を行う前に、rdtsc を 2 回連続して呼び出してオーバーヘッドを測定しています。これを for ループで何度も繰り返し、平均値を rdtsc オーバーヘッドとして使用します。
まず平均値を使うということでよろしいでしょうか?
それにもかかわらず、ここでの大きな問題は、オーバーヘッドの負の値が得られることがあることです (必ずしも平均化されたものではなく、少なくとも for ループ内の部分的なもの)。
これは、操作に必要な CPU サイクル数の連続計算にも影響し、sem_wait()
負になることもあります。私が書いたことが明確でない場合は、ここに私が取り組んでいるコードの一部があります。
なぜ私はそのような負の値を得ているのですか?
(編集者注:完全な 64 ビット タイムスタンプを取得するための正確で移植可能な方法については、CPU サイクル カウントを取得しますか?"=A"
を参照してください。asm 制約は、x86-64 用にコンパイルされた場合、レジスタ割り当てが発生するかどうかに応じて、下位または上位 32 ビットのみを取得します。出力に RAX または RDX を選択しuint64_t
ます。選択しませんedx:eax
。)
(編集者の 2 番目のメモ: おっと、それがなぜ否定的な結果が得られたのかについての答えです。このrdtsc
実装をコピーしないようにという警告として、ここにメモを残しておく価値があります。)
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
static inline uint64_t get_cycles()
{
uint64_t t;
// editor's note: "=A" is unsafe for this in x86-64
__asm volatile ("rdtsc" : "=A"(t));
return t;
}
int num_measures = 10;
int main ()
{
int i, value, res1, res2;
uint64_t c1, c2;
int tsccost, tot, a;
tot=0;
for(i=0; i<num_measures; i++)
{
c1 = get_cycles();
c2 = get_cycles();
tsccost=(int)(c2-c1);
if(tsccost<0)
{
printf("#### ERROR!!! ");
printf("rdtsc took %d clock cycles\n", tsccost);
return 1;
}
tot = tot+tsccost;
}
tsccost=tot/num_measures;
printf("rdtsc takes on average: %d clock cycles\n", tsccost);
return EXIT_SUCCESS;
}