cpu配列の異なるアクセス方式のパフォーマンステスト
パフォーマンステストプログラムの出力:
1:temp = array[i]*i: 2430.0 ms 2:temp = GET(array,i) *i: 2430.0 ms 3:temp = get(array,i)*i: 2840.0 ms 4:int a = get(array,i);temp = a*i: 3370.0 ms 5:int a = array[i];temp = a*i;: 2010.0 ms 6:temp = *(array+i)*i: 2430.0 ms 7:temp = *(array+i)*i: 2010.0 ms
ここで,GETはマクロ定義,getは関数である.
明らかに、1,2,6は同じで、予想に合っています.(もちろん時々違いますが、近いです)
3関数呼び出しでアクセスし、時間が長く、予想に合致します.
4は3の基礎の上で、また多くの賦値をして、時間は長電して、予想に合います.
5と7は不思議で、彼女は1の基礎の上で間違って値をつけて、時間は意外にも短くなりました.
テストコード
iを乗じた原因でその奇妙な問題が発生したようですが、
iを掛けることを1や2を掛けることに変更すると、できないようです.
しかし、i+1を乗じた場合は予想外だった.
アセンブリコードを見てみましょう.
1:temp = array[i]*i: 2430.0 ms 2:temp = GET(array,i) *i: 2430.0 ms 3:temp = get(array,i)*i: 2840.0 ms 4:int a = get(array,i);temp = a*i: 3370.0 ms 5:int a = array[i];temp = a*i;: 2010.0 ms 6:temp = *(array+i)*i: 2430.0 ms 7:temp = *(array+i)*i: 2010.0 ms
ここで,GETはマクロ定義,getは関数である.
明らかに、1,2,6は同じで、予想に合っています.(もちろん時々違いますが、近いです)
3関数呼び出しでアクセスし、時間が長く、予想に合致します.
4は3の基礎の上で、また多くの賦値をして、時間は長電して、予想に合います.
5と7は不思議で、彼女は1の基礎の上で間違って値をつけて、時間は意外にも短くなりました.
テストコード
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define GET(array,index) array[index]
int get(int *array,int index)
{
return array[index];
}
int main(void)
{
clock_t start,stop;
float elapsedTime;
int rounds = 10000;
int array_size = 100000;
int *array = new int[array_size];
for(int i=0;i<array_size;i++)
{
array[i]=i;
}
int temp = 0;
start = clock();
for(int round=0;round<rounds;round++)
{
for(int i=0;i<array_size;i++)
{
temp = array[i]*i;
}
}
stop= clock();
elapsedTime = (float)(stop - start) /
(float)CLOCKS_PER_SEC * 1000.0f;
printf( "1:temp = array[i]*i: %3.1f ms
", elapsedTime );
start = clock();
for(int round=0;round<rounds;round++)
{
for(int i=0;i<array_size;i++)
{
temp = GET(array,i) *i;
}
}
stop= clock();
elapsedTime = (float)(stop - start) /
(float)CLOCKS_PER_SEC * 1000.0f;
printf( "2:temp = GET(array,i) *i: %3.1f ms
", elapsedTime );
start = clock();
for(int round=0;round<rounds;round++)
{
for(int i=0;i<array_size;i++)
{
temp = get(array,i)*i;
}
}
stop= clock();
elapsedTime = (float)(stop - start) /
(float)CLOCKS_PER_SEC * 1000.0f;
printf( "3:temp = get(array,i)*i: %3.1f ms
", elapsedTime );
start = clock();
for(int round=0;round<rounds;round++)
{
for(int i=0;i<array_size;i++)
{
int a = get(array,i);
temp = a*i;
}
}
stop= clock();
elapsedTime = (float)(stop - start) /
(float)CLOCKS_PER_SEC * 1000.0f;
printf( "4:int a = get(array,i);temp = a*i: %3.1f ms
", elapsedTime );
start = clock();
for(int round=0;round<rounds;round++)
{
for(int i=0;i<array_size;i++)
{
int a = array[i];
temp = a*i;
}
}
stop= clock();
elapsedTime = (float)(stop - start) /
(float)CLOCKS_PER_SEC * 1000.0f;
printf( "5:int a = array[i];temp = a*i;: %3.1f ms
", elapsedTime );
start = clock();
for(int round=0;round<rounds;round++)
{
for(int i=0;i<array_size;i++)
{
temp = *(array+i)*i;
}
}
stop= clock();
elapsedTime = (float)(stop - start) /
(float)CLOCKS_PER_SEC * 1000.0f;
printf( "6:temp = *(array+i)*i: %3.1f ms
", elapsedTime );
start = clock();
for(int round=0;round<rounds;round++)
{
for(int i=0;i<array_size;i++)
{
int a = *(array+i);
temp = a*i;
}
}
stop= clock();
elapsedTime = (float)(stop - start) /
(float)CLOCKS_PER_SEC * 1000.0f;
printf( "7:temp = *(array+i)*i: %3.1f ms
", elapsedTime );
return 0;
}
iを乗じた原因でその奇妙な問題が発生したようですが、
iを掛けることを1や2を掛けることに変更すると、できないようです.
しかし、i+1を乗じた場合は予想外だった.
アセンブリコードを見てみましょう.