|
|
2023/5/9(Tue) 18:15:26|NO.99411
忙しい中すみません。
どうか並列処理をおしえてくれませんか。
(無礼ですがまだ初めて3か月なのであまり難しいことはわかりません。)
またあまりはやく返信できないことも謝ります。
返信待っています。
|
|
2023/5/9(Tue) 18:54:19|NO.99412
repeat〜loopとgosubを使えばできると思います(主様のご期待に添えるか分かりませんが...)
repeat
gosub *タグ名1
gosub *タグ名2
await (1000/60)
loop
*タグ名1
// 以下、処理を書く
return
*タグ名2
// 以下、処理を書く
return
|
|
2023/5/10(Wed) 12:56:14|NO.99421
どのような「並列処理」をしたいのかにもよるので何とも言い難いですが、
基本は nennneko5787さん のrepeat〜loop で回して gosub を使う形になるかと。
作りたいモノによってはrepeat 〜 loop じゃなく、
下記のようにgoto 〜 *任意のラベル ジャンプでループを回したりも。
;===========================================================
*main ;
gosub *sub1 ; *sub1 へ一時的にジャンプ
gosub *sub2 ; *sub2 へ一時的にジャンプ
await 20 ; ループ処理にはawait/wait命令必須(ないとバグります)
goto *main ; *main へ戻る
;===========================================================
*sub1 ; 以下 *sub1 処理
mes "サブ1" ; 何か処理させる(とりあえずサブ1と文字表示)
countA+=1 ; 変数で何回文字表示したか回数をカウント。
if countA>=25:cls 0:countA=0 ; カウントが25以上になったら画面を真っ白に消去。カウンターの数字も0に戻す。
return ; gosub *sub1 の行へ戻り、次の行から*mainの処理続行
;-------------------------------------------
*sub2 ; 以下 *sub2 処理
title "A="+countA ; 何か処理させる(とりあえずcountA変数の数字をタイトルに表示)
return ; gosub *sub2 の行へ戻り、次の行から*mainの処理続行
;--------------------------------------------
|
|
2023/5/10(Wed) 22:57:02|NO.99429
●#99425 zakki さん
http://www.hsp.tv/play/pforum.php?mode=pastwch&num=27077
...は、マルチスレッド版ランタイム hsp3mt の事でしょうか?
HSP3アップデートガイドによると
HSP3.6〜同梱終了になってます
4.パッケージの同梱終了
HSP3MTランタイム→hsp3utfやhsp3_64をご使用ください
...とありますが、↑で、マルチコアの高速化が見込めるんでしょうか?
元々、hsp3mtランタイム自体、説明がほとんどなく
私程度では、良く分からなかったのですが...
●#99411 1さん
hsp3mt で⬇️の サイト内検索 をすると出てくるかも
後、並列処理 も同様に検索すると良いと思います
|
|
2023/5/10(Wed) 23:36:07|NO.99431
返信が遅れてすみません。
おそらくできました。
ラグなど問題が発生したらまた返信します。
わかりやすい文も書いていただきありがとうございました。
|
|
2023/5/11(Thu) 01:36:51|NO.99432
当時のことはよく知りませんがドキュメントから推測するに、hsp3mtはhspで書いたコードがマルチスレッド実行されるって話ではなく、
Windows9xの頃との互換性や使用リソース節約のために無印hsp3ランタイムではシングルスレッド用Cランタイムを使ってたのを
(2000以降は標準の)マルチスレッド版Cランタイムを使うようにしたって話じゃないですか?
つまりHSP SDKを使ってC/C++でランタイムやプラグインを拡張するときに、それ以前と比べてスレッド使いやすくなったみたいな違いで今回のとは別件じゃないかと思います。
|
|
2023/5/11(Thu) 20:37:38|NO.99433
>zakki さん
夜分遅くに文献等を調べて頂いたようで
ありがとうございました
...別件でしたか。失礼しました
|
|
2023/5/15(Mon) 17:15:44|NO.99445
すみません。
もう一つ問題が出てきました。
wait を使って並列処理を行うにはどうしたらいいですか?
その場合にはC/C++を使わないとだめなのでしょうか?
|
|
2023/5/15(Mon) 17:40:13|NO.99446
>wait を使って並列処理を行うにはどうしたらいいですか?
>その場合にはC/C++を使わないとだめなのでしょうか?
CPU並列演算ならzakkiさんのご指摘通り、HSP3にその機能はないと思います。自分もCPU並列演算モジュールの存在は知りません。
GPU並列演算なら前記した通り、HSPCL64とHSPCL32Nがあります。
wait処理は特に並列処理と関係ないと思います。C/C++もライブラリを自分で作りたいなどではない限り、この場合関係ないと思います。
並列処理というのは文字通り、処理を同時に実行することであり、それを行うには特別のHSPCL64のようなモジュールが必要です。
|
|
2023/5/16(Tue) 09:11:21|NO.99452
目的はwaitを使いたいだけじゃないと思うので、どういうことをやりたいか書くと回答が付きやすいと思います。
「レイトレーシング計算に10分かかってるけど1コアしか使ってないので10コア100%使って1分にしたい。」みたいな話だと、
↑に書いたような感じでHSPでやるのは大変って回答になります。
例えば、「シューティングゲームでプレイヤーと敵1〜5を、それぞれ違うルートで毎フレーム動かしたいけど、
プレイヤーの動きをrepeatループとwaitで書くと敵の動きのrepeatループをどう書けばいいかわかりません。」とかなら
HSPで対応できます。
|
|
2023/5/21(Sun) 21:26:50|NO.99482
すみません。
返信が遅れました。
それもありますが
数字の計算(実際は高速で1ずつあがっていくもの)と物体の動きとを
NO.99421のさーくんのようにするといしょにすると
計算と同時にその物体も遅くなってしまうことです。
|
|
2023/5/22(Mon) 16:36:59|NO.99486
画面への描画が遅れるくらいに大がかりな計算を行っているということでしょうか?
「計算中にTimeGetTimeで時間を計測し、
一定時間が経ったら一時中断して次の処理に進み、
次回はその続きから計算を行う」という方法もないわけではありません。
以下はやってみた例です。
//モンテカルロ法で円周率を計算。
//正方形の中に「4分の1の円」を描いたものにランダムで2千万回点を打ち、
//「4分の1の円」の中に入る確率を求め、そこから円周率を推測する。
//計算途中で関係のない画面処理も行う。
#include "winmm.as" //TimeGetTimeを使用するのに必要。
#module
#defcfunc rnd10000 //0〜9999の範囲の乱数を偏りなく返す(rnd(10000)では偏りが出るので)
repeat
tmp=rnd(32768)
if tmp<30000 : break
loop
return tmp/3
#global
randomize
count=0
in=0
posx=320 : posy=240
repeat
gosub *calc
if count>=20000000 : break
title str(count)
gosub *other
await 16
loop
//結果表示
color 255,255,255 : boxf : color 0,0,0
pos 0,0 : mes "2千万回中、4分の1の円の中にヒットした回数:"+str(in)
mes "1万×1万の正方形の面積は1億、半径1万の円の4分の1の面積は2500万Π"
mes "円周率Π≒"+str(double(in)/5000000.0)
stop
*calc
//時間のかかる処理の途中で時間を計測し、一定時間経ったら一旦中断。
TimeGetTime : st=stat //TimeGetTimeで現在のタイマー値がstatに入る。
repeat
x=rnd10000() : y=rnd10000()
in+=(x*x+y*y<100000000)
count++
if count>=20000000 : break
TimeGetTime
if stat-st>14 : break //計算している時間が14ミリ秒を超えたら一旦中断する
loop
return
*other
//本筋とは全く関係のない、画面描画をやらせてみる。
//「●」プルプル震えるだけ。
redraw 0
color 255,255,255 : boxf : color 0,0,0
posx=limit(posx+rnd(3)-1,0,639) : posy=limit(posy+rnd(3)-1,0,479)
pos posx,posy : mes "●"
redraw 1
return
実際に質問者さんがどういうコードを組んでいるのかわからないので、
質問者さんのケースにどのように適用すればいいのか、
あるいはそもそも適用可能なのかどうかはわかりかねますが。
| |
|
2023/5/22(Mon) 18:54:16|NO.99487
初めて3カ月との事で、おそらく「並列処理」という言葉だけ先行してしまって、
皆さんが仰るように、「やりたいこと」が分からないのが解決しない問題なんでしょうね。。。
私なんかは、「waitがしたい」との事で、
どこかで非同期処理(async wait)やスレッドに関する様な資料で読んで、
「並行処理でwaitがしたい」と言われているのかと投稿文からパッと思いました。
が、きっともっとシンプルに解決する事で、やりたい事とは違うのかなぁとも考えてます。
言葉での表現が難しければ[1]さんご自分のスクリプトを上げてみるのが近道かもしれませんね。
>wait を使って並列処理を行う
sub1は毎回更新、 sub2は10回に1回更新という
発想でも実質sub2はsub1よりwaitが掛かっていると考える事も出来ますね。
※ sub1はwait 16 sub2は wait 160
あと、ループする形のスクリプトでは
「waitはメインループの中で1回だけで、サブルーチンではwaitはしない」
という組み方の発想を基本とすると、今の所は良いのではと感じました。
matsu = 60 ; ★ここを1とか10とか変えてみても"物体"の動きは遅くならない
*main_loop
gosub *sub1
gosub *sub2
main_time++
await 16 ;wait系はメインループの中で1回だけ
goto *main_loop
*sub1
;↓これがwaitの変わり
if main_time \ matsu != 0 : return ; 60回に1回実行(実質sub2よりwaitが掛かってる)
;計算
keisan+=1
title ""+keisan
return
*sub2
color 255,255,255 : boxf : color 0,0,0
x++
pos x
mes "物体",1
return
|
|
2023/5/23(Tue) 01:12:28|NO.99489
>数字の計算(実際は高速で1ずつあがっていくもの)と物体の動きとを
関係ないかもしれないですが
settimerでそれっぽいのが出来たので貼り付けます
#uselib "user32.dll"
#func SetTimer "SetTimer" int,int,int,int
#func KillTimer "KillTimer" int,int
onexit *exit
oncmd gosub *OnTimer, 0x0113
SetTimer hwnd, 1, 300, 0
repeat
await 1
loop
*OnTimer
pos a/24*110,a\24*20
a++
mes "OnTimer "+cnt
return
*exit
KillTimer hwnd, 1
END
|
|
2023/5/23(Tue) 17:35:45|NO.99491
恥ずかしいですが
cls
pos 90,40
font "MS Pゴシック", 100, 1 | 16
mes "よけゲーム"
color 250,250,230
pos 300,150
button goto "始める" ,*start
stop
*start
x=200
y=200
a=470
b=500
cls
repeat 3,1
pos 300,100
font "MS Pゴシック", 100, 1 | 16
mes 4-cnt
pos 10,10
font "MS Pゴシック", 100, 0 | 16
mes 0
color 200,200,2
circle x,y,a,b
color 0,0,0
line 700,151,0,150
wait 110
cls
loop
q=200
w=150
e=150
r=100
t=50
o=150
u=100
i=100
repeat
redraw 0
color 255,255,255
boxf
q+1
w+1
getkey rrr,37
getkey www,39
if rrr=1{
x-3
a-3
} :物体(緑)が動くところ
if www=1{
x+3
a+3
} :物体(緑)が動くところ
if x<-1{
x+3
a+3
}
if x>371{
x-3
a-3
} :物体緑が端にいかないようにするもの。
:上のIFも同様。
if q=300:{
q-2
w-1
e-1
}
if e=100:{
q+1
e+1
}
if i=0:{
t-l
o-100
u-l
i-100
}
color 0,0,0
line 700,151,0,150
color 0,0,0
circle q,w,e,r
color 200,0,0
circle t,o,u,i
color 200,200,2
circle x,y,a,b
pos 10,3
font "MS Pゴシック", 100, 0 | 16
color 0,0,0
gosub,*qqq
redraw 1
loop
===========================================
*qqq
mes 0+cnt
wait <==今回の疑問
return
|
|
2023/5/23(Tue) 19:24:30|NO.99492
waitのパラメータを省略すると100が指定されたことになるので、
wait 100は1秒待つという意味になりますから、
待ち時間が長すぎなのではありませんか?
こういうアクション的な用途ではwaitよりもawaitの方が良いと思いますので、
たとえばawait 33として30分の1秒だけ待つようにすればどうでしょうか。
(30fps相当)
あと、サブルーチン*qqq内でwait(await)を使うのはあまり適切でないように
思いますので、*qqq内のwaitは削除し、
redraw 1とloopの間にawait文を置いた方が良いように思います。
|
|
2023/5/24(Wed) 17:42:41|NO.99493
恥ずかしくなんてないですよ。正解なんて無いですしコメント付きやすくなるのではないでしょうか。
良い事だと思います。
私からも一例として
もし、mes 0+cnt: wait が「物体の動きに並行処理として1秒waitしてカウントを進めたい」
と考えた結果なのであれば、cntは相性が悪いかと思いました。
(repeatのループ回数の参照用のカウンターなので時間表示には使えない)
下記にスクリプト例を記載します。
正確な秒では無いですが、だいたいゲームの様なものは30か60FPSで
動くように設計されているので、十分かとは思います。
(求める正確性によってタイマーを使うなど設計は変わってきます)
;抜粋と掲示板用に関係無い所を短縮 ★追加、▲削除
x=200:y=200:a=470:b=500:q=200:w=150:e=150:r=100:t=50:o=150:u=100:i=100
counter = 0; ★カウント表示用
repeat
redraw 0 : color 255,255,255 : boxf
q+1 : w+1:getkey rrr,37 : getkey www,39
if rrr=1{x-3:a-3}
if www=1{x+3:a+3}
if x<-1{x+3:a+3}
if x>371{x-3:a-3 }
if q=300{q-2:w-1:e-1:}
if e=100{q+1:e+1:}
if i=0{t-l:o-100:u-l:i-100}
color:line 700,151,0,150
color:circle q,w,e,r
color 200:circle t,o,u,i
color 200,200,2:circle x,y,a,b
pos 10,3:font "MS Pゴシック", 100, 0 | 16:color
gosub,*qqq
redraw 1
await 16;★ループ前に時間待ち16m つまり60FPS程度
loop
*qqq
mes counter;★カウント表示用
if cnt\60=59{ counter+1 };★カウント加算用 60FPSに1回(つまり約1秒毎)
;▲mes 0+cnt
;▲wait;
return
やりたい事とハズレてたら申し訳ないですが、もしコレで当たっているのであれば
「並行処理でwait」という感じでは無く、
zakkiさんが書かれている様な感じで
やりたいことを箇条書きでもよいので補足するとよいと思います。
例)
・弾を避けるゲームで、ゲーム中の"経過時間"を表示したいです。
・ゲーム中はループ(repeat)で弾を動かしてます。
・ループ中に時間を足して計算してますが、早すぎて困ってます。
・1秒毎に時間を更新したいです。
などなど。。。
| |
|
2023/5/24(Wed) 20:11:04|NO.99494
あまりよく分からないながらいつもフィーリングだけでスクリプト組んでるだけなので偉そうなことは言えないんですが、最後の*qqqの部分を次のようにするだけではダメなのでしょうか?
*qqq
mes 0+cnt/100
await 10 ;<==今回の疑問
return
あと提示されたスクリプトは掲示板に載せる時になってからコメント部分を加えられたのでしょうか。セミコロンでなくコロンになっていたりセミコロンが無かったりでそのままでは実行できませんでした。
|
|