1つめは配列を使ったもの、2つめはポインタを使ったもの、3つめはポインタをレジスタに置いたものです。
プログラムの内容は乱数を発生させるプログラムで乱数ファイルを作り、その乱数データを入力として、乱数を単純選択ソートで値の小さいもの順に並べ替えるものです。
以下がそれらのプログラムです。
配列
#include <stdio.h>
#define nmax 100000
void select_sort(int a[], int n)
{
int i,j,min,t;
for(i=0;i<n;i++)
{
min=i;
for(j=i+1;j<n;j++)
if(a[j]<a[min]) min=j;
t=a[min]; a[min] = a[i]; a[i]=t;
}
}
main(){
int a[nmax+1],n,i;
n=0;
while(scanf("%d",&a[n]) !=EOF) n++;
select_sort(a,n);
/* printf("%d\n\n",n);*/
for(i=0;i<n;i++){
/* printf(" &d\n",a[i]);*/
}
}
#include <stdio.h>
#define nmax 100000
void select_sort(int *a, int n)
{
int *ptr1;
int *ptr2;
int *min;
int t;
for(ptr1=a;(ptr1-a)<n; ptr1++){
min=ptr1;
for(ptr2=ptr1+1;(ptr2-a)<n;ptr2++){
if(*ptr2<*min){
min=ptr2;
}
}
t=*min;
*min=*ptr1;
*ptr1=t;
}
}
main()
{
int a[nmax+1], n,i;
n=0;
while(scanf("%d",&a[n])!=EOF) n++;
select_sort(a,n);
/* printf("%d\n\n",n);*/
for(i=0;i<n;i++) {
/*printf("%d\n",a[i]);*/
}
}
#include <stdio.h>
#include <limits.h>
#define nmax 100000
void select_sort(int *a, int n)
{
register int *ptr1;
register int *ptr2;
register int *min;
int t;
for(ptr1=a;(ptr1-a)<n; ptr1++){
min=ptr1;
for(ptr2=ptr1+1;(ptr2-a)<n;ptr2++){
if(*ptr2<*min){
min=ptr2;
}
}
t=*min;
*min=*ptr1;
*ptr1=t;
}
}
main()
{
int a[nmax+1], n,i;
n=0;
while(scanf("%d",&a[n])!=EOF) n++;
a[n+1]=INT_MAX;
select_sort(a,n);
/*printf("%d\n\n",n);*/
for(i=0;i<n;i++) {
/*printf("%d\n",a[i]);*/
}
}
#include<stdio.h>
#define MAX_DIGIT 10000
main(int argc, char *argv[])
{
int i,size,count;
srand(time(&i));
if(argc<2){
size =1000;
}else{
size = atoi(argv[1]);
}
for(count = 0; count < size; count++){
fprintf(stdout,"%6d ", rand() % MAX_DIGIT);
}
}
また実行時間の影響を少なくするために、出力はコメントアウトしました。
以下が測定結果です。
配列
-O1 11.11
-O2 11.11
-O3 16.65
無し 34.21
ポインタ
-O1 13.94
-O2 13.88
-O3 13.88
無し 30.74
レジスタ
-O1 13.88
-O2 13.88
-O3 16.65
無し 38.01
ここで結果について質問です。
私の予想では、レジスタ>ポインタ>配列 の順で速いかと思ったのですが、オプションなしの結果は
ポインタ>配列>レジスタの順でした。
レジスタについて調べてみたら、レジスタをポインタに置けば、
変数のアクセスのためにメモリをアクセスする必要がなくなるので、変数へのアクセスが高速化される、
ということがわかったのでレジスタが最も早いと思ったのですが、結果は違いました。
この理由はなぜですか?
また、最適化オプションは
-O3>-O2>-O1の順でパフォーマンスの向上をしてくれるものだと思ってました。
しかし今回の結果で、オプション-O1と-O2ではどのプログラムでも実行時間にあまり違いがありませんでした。
なぜ-O2にしても速くならなかったのですか?
さらに、-O3のとき、ポインタでは-O1,-O2同様変化がなく、配列とレジスタでは速くなるどころか遅くなっています。
この理由もわかりません。
よろしくお願いします。