アプリ版:「スタンプのみでお礼する」機能のリリースについて

私のこのPCのサンプルプログラムt_calSin.cではsin関数の計算時間は
1usec前後です。

このサンプルプログラムのコンパイルは『cc -o t_calSin t_calSin.c』です。
このサンプルプログラムは『./t_calSin 1000000 1 1』で起動します。
このプログラムは、上記の引数1000000により、1000000回sin関数を計算し
その計算時間の最大値と最小値を表示します。
ラン結果として、計算時間の最大値t_maxは300usec以上となり、
最小値t_minは0usecとなります。

Q1)通常のsin関数の計算時間は1usec前後ですが、時たま300usec以上の
値を示す事があります。
この異常値をなくする方法についてコメント頂けますと大変ありがたいです。
例えば、プライオリティの設定にて、対応するとか。
なお、このプログラムの実行中は他のプログラムの起動は抑止しても
問題はありませんので、その抑止方法のコメントも頂けますと助かります。

=============================
ファイル名:calSin.c
//file: ~/wkSession/t_calSin.c
//cc -o t_calSin t_calSin.c -lm
//mainの引数で指定するjjとiiを使用して、jj*ii回ループして、sin関数の実行時間を求める。
// -im : t_calSin.c:(.text+0x155): `sin' に対する定義されていない参照です
//
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h> //warning: implicit declaration of function 'sleep' is invalid
#include <math.h>


int main(int arc, char* arg[]){
struct timeval tA0, tA1;
double wk;
int t_sec, t_usec;
int t_max, t_min, n_max;
int nn, jj, ii;
printf("Start\n");
if(arc!=4){
printf("arg must be 3--->t_calSin 500 100 4000\n");//nn=500 jj=100 ii=4000
return 1;
}
for(int i=0; i<arc; i++){
printf("arg[%d]=%s ", i, arg[i]);
}
nn=atoi(arg[1]);
jj=atoi(arg[2]);
ii=atoi(arg[3]);
printf("\nnn=%d回ループ sin計算回数:%d(jj)*%d(ii)\n", nn, jj, ii);
t_max=0.0;
t_min=1000.0;
n_max=0;

for(int n=0; n<nn; n++){
gettimeofday(&tA0, NULL);
//=======================
for(int j=0; j<jj; j++){
for(int i=0; i<ii; i++){
wk=(double)(i+j+10);
wk=sin((double)wk);
}
}
//======================
gettimeofday(&tA1, NULL);
//差の時間の表示
t_sec=(tA1.tv_sec-tA0.tv_sec);
t_usec=(tA1.tv_usec-tA0.tv_usec);
t_sec=t_sec*1000000+t_usec;
if(n>0){
if(t_max<t_sec) {t_max=t_sec; n_max=n;}
if(t_min>t_sec) t_min=t_sec;
printf("n=%8d, n_max=%8d, t_sec=%8du, t_max=%8du, t_min=%8du\r",n, n_max, t_sec, t_max, t_min);
fflush(stdout);
}
}
printf("\n");

return 0;
}
以上、宜しくお願いします。

A 回答 (2件)

> 合計はしてないと思いますが



失礼しました。
最初、合計300μだと勘違いしていて、後に合計していないことに気づいたのですが、既に書いていた回答文を修正するのを忘れていました。

> OSのサービスプログラムが割込みが実行
> されているのではなしでしょうか?

ここについては
>加えて、gettimeofdayは現在時刻を返すもので、処理時間を求めるものためのではありません。
以降に書いてあります。
    • good
    • 0

原因の一つは、gettimeofdayの精度です。


1命令がナノ秒(0.001μ秒)オーダーで動作する現在のコンピュータにとって、1μ秒というのは十分に長い時間です。

このプログラムでは
//=======================
for(int j=0; j<jj; j++){
for(int i=0; i<ii; i++){
wk=(double)(i+j+10);
wk=sin((double)wk);
}
}
//======================
のループの実行時間を測定、それを指定回数行なって合計しています。

./t_calSin 1000000 1 1
だと、上記ループは 1*1=1回だけです。
おそらく、1μ秒かからないと思います。
それを、1μ秒しか精度の無いgettimeofdayで測定しようとしているのが、そもそも無理があります。

例えるなら、1分単位でしか表示しない時計を使って、陸上100m走のタイムを測る、というようなものです。
鈍足な私ですが、ボルトと同じ 0分 で走れます。

加えて、gettimeofdayは現在時刻を返すもので、処理時間を求めるものためのではありません。
割り込みとか他プロセス実行とかによる待ち時間も含まれます。
「ネットを使った自動時刻合わせ」の影響も受けます。
https://linuxjm.osdn.jp/html/LDP_man-pages/man2/ …

処理時間だけを求めようと思うなら、別の方法が必要です。
例えば
https://linuxjm.osdn.jp/html/LDP_man-pages/man2/ …

優先順位を変えるには nice コマンドを使います
https://linuxjm.osdn.jp/html/GNU_coreutils/man1/ …


あと、これで求められるのは、ループ全体の時間です。
そこには、sin以外の時間(j<jj を計算して、繰り返すかループ終了するか判定する時間とか、i+j+10を計算する時間とか)も含まれます。
    • good
    • 0
この回答へのお礼

毎度雄世話になります。
>のループの実行時間を測定、それを指定回数行なって合計しています。
<--一回のsinの計算を求めているだけであり、
合計はしてないと思いますが
>1μ秒しか精度の無いgettimeofdayで測定しようとしているのが、そもそも無理があります。
<ーー時たま、300us以上の異常値を示すことが問題です。
OSのサービスプログラムが割込みが実行
されているのではなしでしょうか?

お礼日時:2018/01/07 11:45

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!