HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2023
0509
並列処理について19解決


リンク

2023/5/9(Tue) 18:15:26|NO.99411

忙しい中すみません。
どうか並列処理をおしえてくれませんか。
(無礼ですがまだ初めて3か月なのであまり難しいことはわかりません。)
またあまりはやく返信できないことも謝ります。
返信待っています。



この記事に返信する


nennneko5787

リンク

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の処理続行 ;--------------------------------------------



zakki

リンク

2023/5/10(Wed) 20:36:44|NO.99425

並列計算が言葉通りparallelにマルチコア使った高速化のことでしたら、基本的にHSPではできません。
何かの拡張を使うか、execやpipeexecでプロセスを分ける必要があります。


今後対応したいって話はありました。
http://www.hsp.tv/play/pforum.php?mode=pastwch&num=27077



zrs90(5さい)

リンク

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 で⬇️の サイト内検索 をすると出てくるかも
後、並列処理 も同様に検索すると良いと思います



1

リンク

2023/5/10(Wed) 23:36:07|NO.99431

返信が遅れてすみません。
おそらくできました。
ラグなど問題が発生したらまた返信します。
わかりやすい文も書いていただきありがとうございました。



zakki

リンク

2023/5/11(Thu) 01:36:51|NO.99432

当時のことはよく知りませんがドキュメントから推測するに、hsp3mtはhspで書いたコードがマルチスレッド実行されるって話ではなく、
Windows9xの頃との互換性や使用リソース節約のために無印hsp3ランタイムではシングルスレッド用Cランタイムを使ってたのを
(2000以降は標準の)マルチスレッド版Cランタイムを使うようにしたって話じゃないですか?

つまりHSP SDKを使ってC/C++でランタイムやプラグインを拡張するときに、それ以前と比べてスレッド使いやすくなったみたいな違いで今回のとは別件じゃないかと思います。



zrs90(5さい)

リンク

2023/5/11(Thu) 20:37:38|NO.99433

>zakki さん

夜分遅くに文献等を調べて頂いたようで
ありがとうございました

...別件でしたか。失礼しました



youdai

リンク

2023/5/14(Sun) 18:57:25|NO.99441

GPUによる並列計算であれば、HSP3でも並列計算は可能です。
OpenCLが使用できるモジュールがあります。

HSPCL64が64bit版のHSP3で使用できます。
HSPCL32Nは32bit版のHSP3で使用できます。

HSPCL64
https://github.com/toropippi/HSPCL64

HSPCL32N
https://github.com/toropippi/HSPCL32N

なお、nVidiaのグラフィックボードではnVidia側の不具合で非同期動作が不可であることがあることに注意してください。



1

リンク

2023/5/15(Mon) 17:15:44|NO.99445

すみません。
もう一つ問題が出てきました。
wait を使って並列処理を行うにはどうしたらいいですか?
その場合にはC/C++を使わないとだめなのでしょうか?



youdai

リンク

2023/5/15(Mon) 17:40:13|NO.99446

>wait を使って並列処理を行うにはどうしたらいいですか?
>その場合にはC/C++を使わないとだめなのでしょうか?

CPU並列演算ならzakkiさんのご指摘通り、HSP3にその機能はないと思います。自分もCPU並列演算モジュールの存在は知りません。
GPU並列演算なら前記した通り、HSPCL64とHSPCL32Nがあります。
wait処理は特に並列処理と関係ないと思います。C/C++もライブラリを自分で作りたいなどではない限り、この場合関係ないと思います。

並列処理というのは文字通り、処理を同時に実行することであり、それを行うには特別のHSPCL64のようなモジュールが必要です。



zakki

リンク

2023/5/16(Tue) 09:11:21|NO.99452

目的はwaitを使いたいだけじゃないと思うので、どういうことをやりたいか書くと回答が付きやすいと思います。

「レイトレーシング計算に10分かかってるけど1コアしか使ってないので10コア100%使って1分にしたい。」みたいな話だと、
↑に書いたような感じでHSPでやるのは大変って回答になります。

例えば、「シューティングゲームでプレイヤーと敵1〜5を、それぞれ違うルートで毎フレーム動かしたいけど、
プレイヤーの動きをrepeatループとwaitで書くと敵の動きのrepeatループをどう書けばいいかわかりません。」とかなら
HSPで対応できます。



1

リンク

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
実際に質問者さんがどういうコードを組んでいるのかわからないので、
質問者さんのケースにどのように適用すればいいのか、
あるいはそもそも適用可能なのかどうかはわかりかねますが。



usagi

リンク

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



kinokawa

リンク

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



1

リンク

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文を置いた方が良いように思います。



usagi

リンク

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
 あと提示されたスクリプトは掲示板に載せる時になってからコメント部分を加えられたのでしょうか。セミコロンでなくコロンになっていたりセミコロンが無かったりでそのままでは実行できませんでした。



ONION software Copyright 1997-2023(c) All rights reserved.