実行時間を計測すると
変な事が分かるようになるかも知れない…。
例えば良くある画像のブレンド処理。
二枚の画像をブレンドして出力する場合
このような処理になると思う…。
面倒なので他の処理も一気に書いたりする…。
#include <windows.h>
#include <stdio.h>
/*------------------------------------*/
#define SIZE_X 800
#define SIZE_Y 600
#define IMAGE_SIZE (SIZE_X*SIZE_Y*3)
/*------------------------------------*/
unsigned char output_pixel[IMAGE_SIZE];
unsigned char source_pixel[IMAGE_SIZE];
unsigned char object_pixel[IMAGE_SIZE];
/*--------------------------------------
ごく普通にそのまんまプログラムにおこすと
多分こんなプログラム。
--------------------------------------*/
void blend_a(unsigned char*output,unsigned char*source,unsigned char*object,int size_x,int size_y,int blend)
{
int i,source_blend;
source_blend=0x100-blend;
for(i=size_x*size_y;i>0;i--)
{
output[0] =(source[0]*source_blend+object[0]*blend)/0x100;
output[1] =(source[1]*source_blend+object[1]*blend)/0x100;
output[2] =(source[2]*source_blend+object[2]*blend)/0x100;
source +=3;
object +=3;
output +=3;
}
}
/*--------------------------------------
割り算をシフトに換えて高速化
--------------------------------------*/
void blend_b(unsigned char*output,unsigned char*source,unsigned char*object,int size_x,int size_y,int blend)
{
int i,source_blend;
source_blend=0x100-blend;
for(i=size_x*size_y;i>0;i--)
{
output[0] =(source[0]*source_blend+object[0]*blend)>>8;
output[1] =(source[1]*source_blend+object[1]*blend)>>8;
output[2] =(source[2]*source_blend+object[2]*blend)>>8;
source +=3;
object +=3;
output +=3;
}
}
/*--------------------------------------
演算部分をテーブル化して高速化
--------------------------------------*/
unsigned char blend_table[0x101][0x100];
void blend_c(unsigned char*output,unsigned char*source,unsigned char*object,int size_x,int size_y,int blend)
{
int i;
unsigned char*source_blend,*object_blend;
source_blend=blend_table[0x100-blend];
object_blend=blend_table[blend];
for(i=size_x*size_y;i>0;i--)
{
output[0] =source_blend[source[0]]+object_blend[object[0]];
output[1] =source_blend[source[1]]+object_blend[object[1]];
output[2] =source_blend[source[2]]+object_blend[object[2]];
source +=3;
object +=3;
output +=3;
}
}
/*--------------------------------------
3バイト単位を1バイト単位で処理した時の
実行速度の比較
--------------------------------------*/
void blend_d(unsigned char*output,unsigned char*source,unsigned char*object,int size_x,int size_y,int blend)
{
int i;
unsigned char*source_blend,*object_blend;
source_blend=blend_table[0x100-blend];
object_blend=blend_table[blend];
for(i=size_x*size_y*3;i>0;i--)
{
*output =source_blend[*source]+object_blend[*object];
source++;
object++;
output++;
}
}
/*------------------------------------*/
void main(void)
{
DWORD t[5];
int i, j;
/* 別に初期化しなくても良いんだけど… */
for(i=0;i<=0x100;i++)
for(j=0;j<0x100;j++)
blend_table[i][j]=(i*j)>>8;
for(i=0;i<IMAGE_SIZE;i++)
source_pixel[i]=object_pixel[IMAGE_SIZE-1-i]=i;
t[0]=GetTickCount();
for(i=0x100;i>=0;i--)
blend_a(output_pixel,source_pixel,object_pixel,SIZE_X,SIZE_Y,i);
t[1]=GetTickCount();
for(i=0x100;i>=0;i--)
blend_b(output_pixel,source_pixel,object_pixel,SIZE_X,SIZE_Y,i);
t[2]=GetTickCount();
for(i=0x100;i>=0;i--)
blend_c(output_pixel,source_pixel,object_pixel,SIZE_X,SIZE_Y,i);
t[3]=GetTickCount();
for(i=0x100;i>=0;i--)
blend_d(output_pixel,source_pixel,object_pixel,SIZE_X,SIZE_Y,i);
t[4]=GetTickCount();
printf("blend_a = %d (%f)\n",t[1]-t[0],(double)(t[1]-t[0])/0x101);
printf("blend_b = %d (%f)\n",t[2]-t[1],(double)(t[2]-t[1])/0x101);
printf("blend_c = %d (%f)\n",t[3]-t[2],(double)(t[3]-t[2])/0x101);
printf("blend_d = %d (%f)\n",t[4]-t[3],(double)(t[4]-t[3])/0x101);
}
※「Release」で結果を確認してね。
「Debug」だと正しい結果が得られないので…。
※ちなみにテストPCのスペックは…
CPUPⅢ500MHz/メモリ287MB
なので結果は、その辺を考慮してね…。
たぶん最近のPCでやると全然違うはず…。
結果…
blend_a = 9255 (36.011673)
blend_b = 7386 (28.739300)
blend_c = 6921 (26.929961)
blend_d = 8334 (32.428016)
「blend_a-blend_b」から
割り算は、シフトにすると劇的に速くなる!
事が分かる。
「blend_b-blend_c」から
テーブル化でさらに高速化!
シフト程でないのが歯痒い…。
もっと差が出て欲しいが…。
ちなみにメモリーアクセスが異様に
高速化された最近のPCならもっと
良い数値が出ると思われる…。
「blend_c-blend_d」から
「for」ループは、重い…。
出来る限りループしない方が速い。
等が分かる…。
時間が有れば、色々計測すると
スピードアップの勘所を
養えるかも知れないし…
養えないかも知れない…。
最近のコメント