• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:実行時間の計測(C言語))

実行時間の計測(C言語)における不可思議な現象とその理由

noname#208507の回答

  • ベストアンサー
noname#208507
noname#208507
回答No.7

書き忘れました。私が試したのは 64bit の Ubuntu 12.04 です。 それから前言を撤回します。仮想環境でなくても1,2間で処理時間が増えない場合はありますね。 別のPCも含めて、再度試してみました。 -------------------------- Ubuntu 12.04 (64bit) Core i7-3720QM 2.6 GHz (8 core) (1) 3.431967 sec (2) 3.943790 sec (3) 6.874282 sec (4) 10.425479 sec (5) 3.392887 sec (6) 3.918412 sec (7) 4.458465 sec (8) 3.947680 sec -------------------------- Vine 6.0 (32bit) Core2 Duo T7250 2.0 GHz (2 core) (1) 7.082609 sec (2) 7.086212 sec (3) 12.156981 sec (4) 18.270035 sec (5) 7.082886 sec (6) 7.069174 sec (7) 7.393213 sec (8) 9.099289 sec -------------------------- Vine 3.2 (32bit) Mobile Celeron 1.8 GHz (1 core) (1) 4.712198 sec (2) 6.769757 sec (3) 13.794606 sec (4) 21.499377 sec (5) 4.516656 sec (6) 6.848446 sec (7) 9.207516 sec (8) 11.300254 sec -------------------------- 全て native install です。また最適化はしていないので、加算命令(64bitはaddq, 32bitはaddl)もCのコードと素直に対応しています。やはり古いCeleronは、他よりも処理が時間に反映されている気がしますね。 同じメモリへの加算より、違うメモリへの加算の方が時間の増え方が鈍いです。キャッシュには余裕で入りきるサイズでしょうから、パイプラインが影響している気がしますが。 他の皆さんも言われている通り、要因が多すぎて確かなことは不明です。

nit_dahlia
質問者

お礼

ありがとうございます。 いろいろと実験してくださったんですね。 私も、Corei3にUbunutu12.04をnative installしてみました。 やはり、結果はulist様と同様もののでした。 (私も最適化していません。) >同じメモリへの加算より、違うメモリへの加算の方が時間の増え方が鈍いです 違うメモリへの加算((5)~(8))の実行時間が増えにくいのは、 ほぼパイプラインの影響でしょうね。 (1)(2)間もしkは、(5)(6)間で基本的に、実行時間があまり増えない理由が いろいろ調べているのですが、まだ分からないです。 Celeronの結果を見ると、 (2)~(4)では線形的に時間が増えていっていて、 つじつまが合いますよね。 しかし、(1)~(2)間だけがどうしても説明ができない…。 どこに理由があるのでしょうね。

関連するQ&A

  • UNIX times関数を用いた時間計測

    以下のようなforkを使用したプログラムの実行時間を計測したいのですが、times関数の使用方法がわかりません。 gettimeofdayを用いて物理的な実行時間を計測することは出来たのですが、 それでは不充分なので、もっと詳細に計測したいのです。 times関数を用いると ・実行中のプロセスが消費したユーザCPU時間 ・実行中のプロセスが消費したシステムCPU時間 ・子プロセスが消費したユーザCPU時間 ・子プロセスが消費したシステムCPU時間 がわかりますよね?sysconf()でクロック時間を得るところまでは出来たのですが、アドバイスお願いします。 #include <stdio.h> #include <sys/time.h> #include <sys/times.h> #include <unistd.h> int main(int argc, char *argv[]) { int val ; struct timeval tv,tw; gettimeofday(&tv,NULL); time = times(&t); switch(fork()) { case 0: exit(0) ; case -1: perror("child process") ; break; default: wait(&val) ; } gettimeofday(&tw,NULL); time = tw.tv_usec - tv.tv_usec; printf("child PID = %d\n",cpid); printf("val = %d\n"); printf("%ldus\n",time); }

  • 処理時間計測

    処理時間計測用関数を #include <sys/timeb.h> struct _timeb tb; double gettimeofday_msec() { _ftime( &tb ); return ((double)tb.time * 1000.0) + ((double)tb.millitm); } と定義したのですが、これをどのように使えばいいのでしょうか? 教えてください。

  • 並列プログラミングのエラー

    6400×6400の行列のベクトル積を並列計算によって求め、その時間を計るプログラムです。 #include <stdio.h> #include <stdlib.h> #include <sys/time.h> #include <pthread.h> #define MATRIX 6400 #define THREAD 2 #define COUNT 30 #define SPLIT 100 int INDEX = 0; double a[MATRIX * MATRIX], b[MATRIX], x[MATRIX]; pthread_mutex_t m1; double gettimeofday_sec() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + (double)tv.tv_usec*1e-6; } void thread_func(void *arg) { int i, j, tmp; while(INDEX < MATRIX) { pthread_mutex_lock(&m1); tmp = INDEX; INDEX += SPLIT; pthread_mutex_unlock(&m1); for(i = tmp; i < tmp + SPLIT; i++) { for(j = 0; j < MATRIX; j++) { b[i] += a[i * MATRIX + j] * x[j]; } } } } int main() { int i, j; double timeA, timeB; pthread_t handle[THREAD]; pthread_mutex_init(&m1, NULL); for(i = 0; i < MATRIX * MATRIX; i++) a[i] = rand() % 10; for(i = 0; i < MATRIX; i++) x[i] = rand() % 10; timeA = gettimeofday_sec(); //計測開始 for(i = 0; i < COUNT; i++) { for(j = 0; j < THREAD; i++) pthread_create(&handle[i], NULL, (void *)thread_func, NULL); for(j = 0; j < THREAD; i++) pthread_join(handle[i], NULL); INDEX = 0; } timeB = gettimeofday_sec(); //計測終了 printf("計算時間:%d\n", timeB - timeA); return 0; } cygwinでコンパイル、実行すると Exception: STATUS_ACCESS_VIOLATION at eip=00401276 eax=000018D0 ebx=000018FF ecx=00000003 edx=0022CE64 esi=611021A0 edi=004015E8 ebp=0022CCE8 esp=0022CC90 program=C:\cygwin\home\管理者\a.exe, pid 2020, thread main cs=001B ds=0023 es=0023 fs=003B gs=0000 ss=0023 Stack trace: Frame Function Args 0022CCE8 00401276 (00000001, 6116B690, 13F40090, 0022CC70) 0022CD98 610060D8 (00000000, 0022CDD0, 61005450, 0022CDD0) 61005450 61004416 (0000009C, A02404C7, E8611021, FFFFFF48) 7 [main] a 2020 _cygtls::handle_exceptions: Error while dumping state (probably corrupted stack) という内容のstackdumpファイルが生成されて実行できません。 どのように修正すればうまく実行できるでしょうか? 環境は OS:WindowsXP SP3 CPU:Intel(R) Core(TM)2 Duo E4500 @2.20GHz RAM:2048MB です。 よろしくお願いします。

  • c言語でDFTのプログラムを作成したのですが

    c言語でDFTのプログラムを作成しました。 以下にソースを載せます。 #include<stdio.h> #include<math.h> #include<stdlib.h> #include<time.h> #define PI 3.141592653589793 #define N 64 //データ数 DFT(double result[]){ int i,k; double A[N],B[N],T=0; //A[N]:実数部,B[N]:虚数部 double a,b; for(k=0;k<N;++k){ a=b=0; for(i=0;i<N;++i){ a=a+result[i]*cos(2*PI*i*k/N);      b=b+(-1.0)*result[i]*sin(2*PI*i*k/N); } A[k]=a/N; B[k]=b/N; } for(i=0;i<N;++i){ printf("[%f秒]:Re:%f,Im:%f\n",T,A[i],B[i]); //変換後の値を表示 T=T+(0.1/N); } } main(){ int i; double T=0; double Sampdata; double result[N]; for(i=0;i<N;++i){ Sampdata=5*sin(20*PI*T);      //0~0.1秒間をN個にサンプリング result[i]=Sampdata; //サンプリングデータを代入 T=T+(0.1/N); } clock_t start,end; //処理時間計測開始 start=clock(); DFT(result); end=clock(); printf("%.2f秒かかりました\n",(double)(end-start)/CLOCKS_PER_SEC); //処理時間表示 } 元信号には5sin(20πt)の値を入れています。この信号は周期は0.1secです。 これでフーリエ変換を行うとデータ数N/2を中心に対称なデータが出てくるのですが、処理が終わるのが早い気がするんです。 例えば2^15個のデータで実行しても2分もかからずに処理が終わってしまいます。一応、対称性が出てるとはいえ、終わるのが早すぎる気がするのですが、おかしい所があれば教えていただけると嬉しいです。 よろしくお願いします。

  • 計算処理時間を出力したい!

    素因数分解を行うプログラムにおいて、処理時間を計算する必要があります。 #include <stdio.h> #include <time.h> main() unsigned long i,t0,t1; t0 = clock(); for(i=0; i<100000; i++){ } t1 = clock(); printf("Time : %lf\n", t1 - t0); } などと例を作ってテストしているのですが、小さな単位まで出てきません。 100分の1秒単位で出てきているとおもいます。 もっと細かい時間を計測するのにはどうしたらいいのでしょうか?

  • C言語:計算問題を解く時間が計測できません

    C言語を学び始めて1週間程度のものです。 現在柴田望洋著の明解C言語中級編という本でC言語を学んでいます。 その中のプログラミング例を真似してプログラミングしているのですが、 うまく動作しません。詳細は以下の通りです。 著書のList2-6のプログラミングです。 問題:計算問題を解く時間を計測が0.0秒になってしまう。 ここよりプログラミングです。 #include <time.h> #include <stdio.h> #include <stdlib.h> int main (void) { int a, b, c; int x; clock_t start, end; double req_time; srand(time(NULL)); a = 10 + rand() % 90; b = 10 + rand() % 90; c = 10 + rand() % 90; printf("%d + %d + %dは何ですか:", a, b, c); start = clock(); while (1) { scanf("%d", &x); if (x == a + b +c) break; printf("\a違いますよ!!\n再入力してください:"); } end = clock(); req_time = (double)(end - start) / CLOCKS_PER_SEC; printf("%.1f秒かかりました。\n", req_time); if (req_time > 30.0) printf("時間がかかりすぎです。\n"); else if (req_time > 17.0) printf("まあまあですね。\n"); else printf("素早いですね\n"); return (0); } このプログラムを実行して計算を解いて正解の答えを入力しても 0.0秒かかりました。 素早いですね。 としかでてきません。どうすればきちんと時間を計測するプログラミングができるでしょうか。 パソコンはMacbookairを使っています。 コンパイラ(?)はXcodeというものを使っていると思います(ここらへんは勉強不足でよくわかりません。) もしよければご回答お願いします。

  • C言語

    【プログラム】 #include<stdio.h> int main (void) { int i,n; long a; scanf("%d",&n); a=1; for(i=1;i<=n;i++){ printf("%3d回目 %12ld\n",i,a); a=a*2; } return 0; 【実行結果】("33"と入力) 33 1回目      1 2回目      2 3回目      4 4回目      8  :        :  :        : 31回目 1073741824 32回目 -2147483648 33回目      0 【質問】 2倍していくと、32回目に負の数になり さらに33回目には0になりました。 こうなる理由を教えてください。 私は高2です。 出来ればわかりやすくお願いします。

  • C言語の実行について、

    #include <stdio.h> #define N 2 void main(void) { int i ,j ; for( i=1 ; i <= N ; ++i) { for( j=i ; j < N+2 ; ++j) { printf("j=%d\n",j); } printf("i=%d\n",i); } } を実行すると、 j=1,j=2,j=3,i=1,j=2,j=3,i=2となったんですが、 どういった順序で行われているのでしょうか? よろしくお願いします。

  • C言語

    forの直後で1+2+3+4+5+・・・・・・・と加算し続ける式がわからないので教えてください。 #include<stdio.h> int main(void) { char moji; int i,sum; printf("正の整数を1から順に加算します。n\"); printf("加算を開始してよろしいですか。(Y=実行。N=終了)\n"); moji=getchar(); if(moji==y) { for(i=2;sum>=1001;i++) { この部分がわかりません; printf("加算値は%dです。¥n",sum); } }else if(moji=='n'){ printf("終了します。\n"); }else{ printf("YまたはNを入力してください。\n"); } return 0; }

  • C言語に直して下さい

    VisualC++で円周率を求めるプログラムなのだそうですが、 自分はC言語しか使ったことがないため、よく分かりません。 Cでコンパイルできるように直していただけないでしょうか。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 21 #define K 100000 void add(unsigned long a[],unsigned long b[]) { int c = 0, tmp; for (int i = N - 1; i > -1; i--) { tmp = a[i] + b[i] + c; a[i] = tmp % K; c = tmp / K; } } void sub(unsigned long a[],unsigned long b[]) { int c = 0, x = 0; for (int i = N - 1; i > -1 ; i--) { x = c; if (a[i] < b[i] + x ) c = 1; else c = 0; a[i] = c * K + a[i] - b[i] - x; } } void div(unsigned long a[], unsigned long x) { int c=0, tmp; if (x >= K) { printf("Div Error\n"); getchar(); exit(1); return; } for (int i = 0; i < N ; i++) { tmp = (a[i] + c * K) / x; c = (a[i] + c * K) % x; a[i] = tmp; } } void clear(unsigned long a[]) { memset(a,0x00,sizeof(a)*N); } void set(unsigned long a[], unsigned long b[]) { memcpy(a,b,sizeof(a)*N); } void set(unsigned long a[], unsigned long b) { if (b<K) { clear(a); a[0]=b; } } int _tmain(int argc, _TCHAR* argv[]) { unsigned long pai[N], fn[N], gn[N], tmp1[N], tmp2[N]; int i; unsigned long n; clear(pai); clear(fn); clear(gn); clear(tmp1); clear(tmp2); set(fn, 16*5); set(gn, 4*239); for(n=0;n<40000;n++) { div(fn, 25); div(gn, 239); div(gn, 239); set(tmp1, fn); div(tmp1, 2*n+1); set(tmp2, gn); div(tmp2, 2*n+1); if (n%2==0) { add(pai, tmp1); sub(pai, tmp2); }else{ add(pai, tmp2); sub(pai, tmp1); } } for (i=0;i<N;i++) { printf("%5lu ", pai[i]); } getchar(); return 0; }