プログラムの処理時間を計測するための関数の利用例として、\ref{sec:osi-basic-benchmark}で紹介した素数を求めるプログラムをC言語で記述したものを「エラトステネスのふるい:sieve.c」に示します。
sieve.cではプログラムの実行時間を計測するために以下のライブラリ関数が使用されています。
- initexectime()は計時機能の時間を0に初期化します。
- getexectime()は経過時間を秒単位で返します。
#include <xcore.h>
#define MAXSQRT 100
#define MAX MAXSQRT*MAXSQRT
void main()
{
char prime[MAX] ;
int i, j ;
initexectime() ; // 計時時間の初期化
cputs("INIT TABLE\n") ;
for (i = 2; i < MAX; i++)
prime[i] = 1 ;
cprintf("DONE: %d sec\n", getexectime()) ; // 経過時間の表示
cputs("SIEVE\n") ;
for (i = 2; i < MAXSQRT; i++) {
if (prime[i]) {
cprintf("%d,", i) ;
for (j = i; i * j < MAX; j++)
prime[i * j] = 0 ;
}
}
t = getexectime() ; // 経過時間の取得
cprintf("\nDONE: %d sec\n", t) ;
cputs("\nPRIME NUMBERS\n") ;
for (i = 2; i < MAX ; i++) {
if (prime[i])
cprintf("%d,", i) ;
}
cprintf("\nEXEC TIME: %d sec\n", t) ;
wexit() ;
}
エラトステネスのふるい:sieve.c
プログラムをコンパイルして6502-CORE で実行した例を「sieve.cの実行結果」に示します。
計算結果の表示を除く計算時間は8秒(2MHz)でした。
\ref{sec:apple1-basic-exec}節に、BASICで書かれたSIEVEの実行例を示しています。
同じアルゴリズムのプログラムですが、実行時間はやはりというか当然というか、こちらのCで書かれた方が9倍程度高速です。
sieve.cのmapファイルのSegment listを「生成コードのメモリマップ:sieve.c」に示します。
Segment list:
-------------
Name Start End Size Align
----------------------------------------------------
ZEROPAGE 000080 000099 00001A 00001
STARTUP 001000 001016 000017 00001
ONCE 001017 001022 00000C 00001
CODE 001023 0018CF 0008AD 00001
RODATA 0018D0 00199E 0000CF 00001
DATA 00199F 0019D5 000037 00001
BSS 0019D6 001A01 00002C 00001
生成コードのメモリマップ:sieve.c
sieve.cの行数(処理内容)は、これまでのプログラムの中で最大ですが、コードサイズは同じようにcprintf()を使用しているevalpr.cより200バイト程度多いだけで、sieve.cで使用していないcscanf関数を使用しているevalprsc.cに比べれば、2KB以上小さなサイズとなっています。
Cの小さなプログラムでは、プログラムの行数以上に使用するライブラリ関数がコードサイズの大小に影響を与えることが確認できます。