ES-BASIC #13
はじめに
(19-3) 結果のまとめ
言語 | 処理系のインストールサイズ | タイプ | 実行時間 | GCC x64 -O3比 | 備考 | GCC x64 8.1.0 -O3 | 449256KB | コンパイラ言語 | 1.115秒 | 1.00倍 | これはコンパイル時間を含んでいません。ちなみにコンパイル時間は0.37秒でした(これは複数回試した最小値です)。 | ES-BASIC ver.0.1b 64bit版 | 102KB | スクリプト言語 | 1.270秒 | 1.14倍 | これはJITコンパイル時間を含んでいます。GCCに対して、1.14倍くらいの時間がかかっていることになります。 | Ruby 2.6.4p104 x64 | 75323KB | スクリプト言語 | 76.102秒 | 68.2倍 | | Python 3.7.4 | 85771KB | スクリプト言語 | 344.891秒 | 309倍 | |
(19-4) gcc x64 8.1.0 -O3
- gccでは以下の「19-1d.c」が最も高速に計算できたので、このコードで処理時間を測定しました。
// "19-1d.c"
#include <stdio.h>
#include <time.h>
int main()
{
int n, sn, h = 0;
long long x, y, cx, cy, zx, zy, xx, yy, xx0;
for (y = -125152; y > -211168; y -= 224) {
for (x = 4673760; x < 4788448; x += 224) {
sn = 7152;
for (cx = x - 224; cx < x; cx += 56) {
xx0 = (cx * cx) >> 24;
for (cy = y + 224; cy > y; cy -= 56) {
zy = cy;
zx = cx;
xx = xx0;
yy = (cy * cy) >> 24;
n = -446;
do {
zy = (zy * zx) >> 23;
zx = xx + cx - yy;
zy = zy + cy;
n++;
if (n >= 0) goto skip;
xx = (zx * zx) >> 24;
yy = (zy * zy) >> 24;
} while (xx + yy <= 0x4000000);
sn += n;
skip:
;
}
}
h += sn >> 4;
}
}
printf("h=%d\n", h);
printf("time=%.3f[sec]\n", (float) clock() / CLOCKS_PER_SEC);
return 0; // dummy
}
- これを実行すると、手元の環境では以下のようになりました。
h=28656617
time=1.115[sec]
(19-5) ES-BASIC ver.0.1b 64ビット版
- ES-BASICでは以下のコードで処理時間を測定しました。
1 $DI=R07; // R07を自由に使いたいときは事前にこれを実行する必要がある
2 ALIAS ZX:R01, ZY:R03, XX:R06, YY:R07, CX:R08, CY:R09, XX0:R10, N:R11, SN:R12, X:R13, Y:R14, H:R15
3 H=0
4 FORNE Y=_125152,_211168,_224
5 FORNE X=4673760,4788448,224
6 SN=7152; // 447*16
7 FORNE CX=X-224,X,56
8 XX0=CX*:CX>>24
9 FORNE CY=Y+224,Y,_56
10 ZY=CY
11 ZX=CX
12 XX=XX0
13 YY=CY*:CY>>24
14 N=_446
15 DOLOOP
16 ZY=ZY*:ZX>>23
17 ZX=XX+CX-YY
18 ZY=ZY+CY
19 N=N+1
20 IF >=0 GOTO SKIP
21 XX=ZX*:ZX>>24
22 YY=ZY*:ZY>>24
23 ENDDO XX+YY<=0X4000000
24 SN=SN+N
25 LABEL SKIP
26 NEXT
27 NEXT
28 SN=SN>>4
29 H=H+SN
30 NEXT
31 NEXT
32 PRINT H
- 実行結果は以下のようになります。
28656617
(1.270[sec])
- ちなみにこのプログラムでは、R00とR02の利用を避けて、さらに乗算に A*:B>>C 形式を使うことで、32ビット版のES-BASICでも同じ結果が得られるようになっています(内部では、IMULを使って結果をEDX:EAXに生成した後、SHRD EAX,EDX,24でシフトしている)。でも32ビット版では速度が落ちて、1.899秒くらいはかかります。
(19-6) Ruby 2.6.4p104 x64
(19-7) Python 3.7.4
- Pythonでも浮動小数点演算を使ったほうが高速だったので、19-1eのアルゴリズムを使いました。
import time
start = time.time()
h = 0
C24 = 1.0 / 16777216.0
y = -125152
while y > -211168:
x = 4673760
while x < 4788448:
sn = 7152
ix = x - 224
while ix < x:
cx = ix * C24
xx0 = cx * cx
iy = y + 224
while iy > y:
cy = iy * C24
zy = cy
zx = cx
xx = xx0
yy = cy * cy
n = -446
while xx + yy <= 4.0:
zy = zy * zx * 2.0
zx = xx + cx - yy
zy = zy + cy
n += 1
if n >= 0: break
xx = zx * zx
yy = zy * zy
sn += n
iy -= 56
ix += 56
h += sn >> 4
x += 224
y -= 224
print(h)
print(time.time() - start)
- 実行結果は以下のようになりました。
28654722
344.89172649383545
こめんと欄
|