おぼえがき
switch文の代用
HSPのswitchは書きにくくて苦手、、という場合には、下記を使う
①repeat文を使う
repeat 1
if 条件1{break}
if 条件2{break}
if 条件3{break}
loop
②マクロで完璧(usagi師匠)
https://hsp.tv/play/pforum.php?mode=all&num=101164
#define global branch gosub %tbrs *%i : goto %tbre *%i : %tbrs *%o
#define global brend %tbranch %tbre *%o
; ↑これをhspdef.asなどに書いておく
a=0:b=0
branch
if (a=1)&(b=1):mes "1":return
if (a=2)&(b=1):mes "2":return
if (a=3)&(b=1):mes "3":return
mes "条件を満たしませんでした"
brend
DLLとは何ぞや
https://qiita.com/AmefuriTell/items/6530371adf16bf5f2063
1)Cソース"accelerate.c"
int accMulMtx(double *m1, double *m2, double *dst) {
dst[0] = m1[0] * m2[0] + m1[4] * m2[1] + m1[8] * m2[2] + m1[12] * m2[3];
dst[1] = m1[1] * m2[0] + m1[5] * m2[1] + m1[9] * m2[2] + m1[13] * m2[3];
dst[2] = m1[2] * m2[0] + m1[6] * m2[1] + m1[10] * m2[2] + m1[14] * m2[3];
dst[3] = m1[3] * m2[0] + m1[7] * m2[1] + m1[11] * m2[2] + m1[15] * m2[3];
dst[4] = m1[0] * m2[4] + m1[4] * m2[5] + m1[8] * m2[6] + m1[12] * m2[7];
dst[5] = m1[1] * m2[4] + m1[5] * m2[5] + m1[9] * m2[6] + m1[13] * m2[7];
dst[6] = m1[2] * m2[4] + m1[6] * m2[5] + m1[10] * m2[6] + m1[14] * m2[7];
dst[7] = m1[3] * m2[4] + m1[7] * m2[5] + m1[11] * m2[6] + m1[15] * m2[7];
dst[8] = m1[0] * m2[8] + m1[4] * m2[9] + m1[8] * m2[10] + m1[12] * m2[11];
dst[9] = m1[1] * m2[8] + m1[5] * m2[9] + m1[9] * m2[10] + m1[13] * m2[11];
dst[10] = m1[2] * m2[8] + m1[6] * m2[9] + m1[10] * m2[10] + m1[14] * m2[11];
dst[11] = m1[3] * m2[8] + m1[7] * m2[9] + m1[11] * m2[10] + m1[15] * m2[11];
dst[12] = m1[0] * m2[12] + m1[4] * m2[13] + m1[8] * m2[14] + m1[12] * m2[15];
dst[13] = m1[1] * m2[12] + m1[5] * m2[13] + m1[9] * m2[14] + m1[13] * m2[15];
dst[14] = m1[2] * m2[12] + m1[6] * m2[13] + m1[10] * m2[14] + m1[14] * m2[15];
dst[15] = m1[3] * m2[12] + m1[7] * m2[13] + m1[11] * m2[14] + m1[15] * m2[15];
return 0;
}
2)さっきと同じバッチでコンパイル
3)HSPで実行(ちょっと書き方変えました)
; 自作ライブラリ
#uselib "accelerate.dll"
#func accMulMtx "accMulMtx" var, var, var
; 自作HSP関数
#module
#deffunc myMulMtx array m1, array m2, array dst
dst.0 = m1.0 * m2.0 + m1.4 * m2.1 + m1.8 * m2.2 + m1.12 * m2.3
dst.1 = m1.1 * m2.0 + m1.5 * m2.1 + m1.9 * m2.2 + m1.13 * m2.3
dst.2 = m1.2 * m2.0 + m1.6 * m2.1 + m1.10 * m2.2 + m1.14 * m2.3
dst.3 = m1.3 * m2.0 + m1.7 * m2.1 + m1.11 * m2.2 + m1.15 * m2.3
dst.4 = m1.0 * m2.4 + m1.4 * m2.5 + m1.8 * m2.6 + m1.12 * m2.7
dst.5 = m1.1 * m2.4 + m1.5 * m2.5 + m1.9 * m2.6 + m1.13 * m2.7
dst.6 = m1.2 * m2.4 + m1.6 * m2.5 + m1.10 * m2.6 + m1.14 * m2.7
dst.7 = m1.3 * m2.4 + m1.7 * m2.5 + m1.11 * m2.6 + m1.15 * m2.7
dst.8 = m1.0 * m2.8 + m1.4 * m2.9 + m1.8 * m2.10 + m1.12 * m2.11
dst.9 = m1.1 * m2.8 + m1.5 * m2.9 + m1.9 * m2.10 + m1.13 * m2.11
dst.10 = m1.2 * m2.8 + m1.6 * m2.9 + m1.10 * m2.10 + m1.14 * m2.11
dst.11 = m1.3 * m2.8 + m1.7 * m2.9 + m1.11 * m2.10 + m1.15 * m2.11
dst.12 = m1.0 * m2.12 + m1.4 * m2.13 + m1.8 * m2.14 + m1.12 * m2.15
dst.13 = m1.1 * m2.12 + m1.5 * m2.13 + m1.9 * m2.14 + m1.13 * m2.15
dst.14 = m1.2 * m2.12 + m1.6 * m2.13 + m1.10 * m2.14 + m1.14 * m2.15
dst.15 = m1.3 * m2.12 + m1.7 * m2.13 + m1.11 * m2.14 + m1.15 * m2.15
return
#global
; 簡易計測(パワーアップ)
#module
#uselib "kernel32.dll"
#func QueryPerformanceCounter "QueryPerformanceCounter" var
#func QueryPerformanceFrequency "QueryPerformanceFrequency" var
#deffunc startTimer
freq = 0 : start_time = 0 : end_time = 0
QueryPerformanceFrequency freq
QueryPerformanceCounter start_time
return
#defcfunc stopTimer
QueryPerformanceCounter end_time
return double(end_time - start_time) * 1000 / double(freq)
#global
; 適当に初期化
trials = 100000
ddim out, 16 : ddim m1, 16 : ddim m2, 16
repeat 16
m1.cnt = 0.00003*rnd(32768) : m2.cnt = 0.00003*rnd(32768)
loop
; 速度比較
sum_timeA = 0.0 : sum_timeB = 0.0
repeat 5
mes "計測開始。。。"
startTimer
repeat trials
accMulMtx m1, m2, out
loop
timeA = stopTimer() / trials
sum_timeA += timeA
mes "Cライブラリ時間(1回あたり): "+timeA+"ms"
startTimer
repeat trials
myMulMtx m1, m2, out
loop
timeB = stopTimer() / trials
mes "HSPモジュール時間(1回あたり): "+timeB+"ms"
sum_timeB += timeB
speed = timeB / timeA
mes ""+speed+"倍早い!\n"
loop
ave_timeA = sum_timeA / 5
ave_timeB = sum_timeB / 5
mes strf("終了: [C 平均: %fms, HSP 平均: %fms]", ave_timeA, ave_timeB)