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


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0103
VRAMを使って色を取得したいのですが・・・8解決


リンク

2014/1/3(Fri) 12:40:46|NO.59115

VRAMを使ってpgetよりも早い命令を作っているのですが、2倍程度しか早くなりません・・・
コレよりも早くするには、どうすればいいのでしょうか?


#module//VRAMのモジュール #deffunc vpxget int x,int y mref vramA,66 p=((ginfo_winy-1-y)*ginfo_winx+x)*3 return #defcfunc vpxset int 色 return peek(vramA,p+色) #global #include "kernel32.as"////時間を測定用 ループ回数=100000 randomize:color rnd(256),rnd(256),rnd(256):pset color 0,0,0:mes "VRAMとPGETをそれぞれ"+ループ回数+"回使い、早さを比較します。\n" //ここからVRAM GetTickCount:時間=stat//時間の測定を開始 repeat ループ回数 vpxget 0,0//pxget x,yで色を取得 loop GetTickCount:vram時間=(stat-時間)//時間の測定を終了 color 0,0,0:mes "VRAMは"+vram時間+"ms掛かりました。色はR:"+vpxset(2)+" , G:"+vpxset(1)+" , B:"+vpxset(0)+"です。"//val=vpxset(p1)で色を代入します。p1は2でR、1でG、0でBです。 //ここまでVRAM //ここからPGET GetTickCount:時間=stat//時間の測定を開始 repeat ループ回数 pget 0,0 loop GetTickCount:pget時間=(stat-時間)//時間の測定を終了 R=ginfo_R G=ginfo_G B=ginfo_B color 0,0,0:mes "PGETは"+pget時間+"ms掛かりました。色はR:"+R+" , G:"+G+" , B:"+B+"です。\n" //ここまでPGET color 0,0,0:mes "PGETよりVRAMのほうが"+(pget時間-vram時間)+"ms早く、処理を終了しました。"



この記事に返信する


リンク

2014/1/3(Fri) 14:04:29|NO.59117


module//VRAMのモジュール #deffunc VRAMset mref vramA,66 winx=ginfo_winx winy=ginfo_winy return #deffunc vpxget int x,int y p=((winy-1-y)*winx+x)*3 return #defcfunc vpxset int 色 return peek(vramA,p+色) #global #include "kernel32.as"////時間を測定用 ループ回数=1000000 randomize:color rnd(256),rnd(256),rnd(256):pset color 0,0,0:mes "VRAMとPGETをそれぞれ"+ループ回数+"回使い、早さを比較します。\n" VRAMset//初期設定 //ここからVRAM GetTickCount:時間=stat//時間の測定を開始 repeat ループ回数 vpxget 0,0//pxget x,yで色を取得 loop GetTickCount:vram時間=(stat-時間)//時間の測定を終了 color 0,0,0:mes "VRAMは"+vram時間+"ms掛かりました。色はR:"+vpxset(2)+" , G:"+vpxset(1)+" , B:"+vpxset(0)+"です。"//val=vpxset(p1)で色を代入します。p1は2でR、1でG、0でBです。 //ここまでVRAM //ここからPGET GetTickCount:時間=stat//時間の測定を開始 repeat ループ回数 pget 0,0 loop GetTickCount:pget時間=(stat-時間)//時間の測定を終了 R=ginfo_R G=ginfo_G B=ginfo_B color 0,0,0:mes "PGETは"+pget時間+"ms掛かりました。色はR:"+R+" , G:"+G+" , B:"+B+"です。\n" //ここまでPGET color 0,0,0:mes "PGETよりVRAMのほうが"+(pget時間-vram時間)+"ms("+strf ("%3.2f",double(pget時間)/double(vram時間) )+"倍)早く、処理を終了しました。"
モジュールの部分とmes命令の文章を少し、書き換えました。
3.65倍まで早く出来ましたが、これは取得できた色を変数等に代入しない場合です。変数等に代入すると、1.3倍程度までしか早くなりません。



とおりすがり

リンク

2014/1/3(Fri) 16:05:45|NO.59120

逆に考えると、pgetはもともとそれほど難しい処理をしていないので、そこを高速化してもメリットが小さいということになります。

処理の内容にもよりますが、過去の質問で、単純なループで色を取得するのをやめて、ポイントを押さえた色取得アルゴリズムで大幅に
高速化できたという例がありました。

空さんはどんな処理をどういう目的で高速化したいのでしょうか?



暇人

リンク

2014/1/3(Fri) 16:09:51|NO.59121

一回の処理時間は短くても回数が多くて
少しでも軽くしたいなら新規命令は使えない
新規命令だけで処理を食うしパラメータ渡したらその数分処理食う

ある程度使いやすく無駄な処理時間なくしたいならマクロ使うしか無い
NO.59117のをマクロにするこんな感じ
ついでにウィンドウサイズが4で割れない時にアドレスを間違うのを修正とサイズ可変に対応

#module "mod_vpx"//VRAMのモジュール #deffunc VRAMset mref vramA,66 winx=ginfo_winx+(ginfo_sx-ginfo_winx) //サイズ可変ウィンドウに対応 winym=ginfo_winy-1+(ginfo_sy-ginfo_winy) //一番上のライン winx2=((winx*3+3)&-4) //VRAM横1ラインのサイズ vramptr=varptr(vramA) return #define global vpxget(%1=0, %2=0) p@mod_vpx=(winym@mod_vpx-(%2))*winx2@mod_vpx+(%1)*3 #define global ctype vpxset(%1=0) peek(vramA@mod_vpx,p@mod_vpx+(%1)) //おまけ //vpxrgb x,y でvpx_rgbに24ビットで色が返る //色毎のデータはvpx_r、vpx_g、vpx_bで取得 #define global vpxrgb(%1=0, %2=0) memcpy rgb@mod_vpx,vramA@mod_vpx,3,0,(winym@mod_vpx-(%2))*winx2@mod_vpx+(%1)*3 #define global vpx_rgb (rgb@mod_vpx) #define global vpx_r ((rgb@mod_vpx>>16)) #define global vpx_g ((rgb@mod_vpx>>8)&$ff) #define global vpx_b (rgb@mod_vpx&$ff) #global #include "kernel32.as"////時間を測定用 screen 0,641,481 ループ回数=1000000 randomize:color rnd(256),rnd(256),rnd(256):pset color 0,0,0:mes "VRAMとPGETをそれぞれ"+ループ回数+"回使い、早さを比較します。\n" VRAMset//初期設定 //ここからVRAM GetTickCount:時間=stat//時間の測定を開始 repeat ループ回数 vpxget 0,0//pxget x,yで色を取得 loop GetTickCount:vram時間=(stat-時間)//時間の測定を終了 color 0,0,0:mes "VRAMは"+vram時間+"ms掛かりました。色はR:"+vpxset(2)+" , G:"+vpxset(1)+" , B:"+vpxset(0)+"です。"//val=vpxset(p1)で色を代入します。p1は2でR、1でG、0でBです。 //ここまでVRAM //ここからPGET GetTickCount:時間=stat//時間の測定を開始 repeat ループ回数 pget 0,0 loop GetTickCount:pget時間=(stat-時間)//時間の測定を終了 R=ginfo_R G=ginfo_G B=ginfo_B color 0,0,0:mes "PGETは"+pget時間+"ms掛かりました。色はR:"+R+" , G:"+G+" , B:"+B+"です。\n" //ここまでPGET color 0,0,0:mes "PGETよりVRAMのほうが"+(pget時間-vram時間)+"ms("+strf ("%3.2f",double(pget時間)/double(vram時間) )+"倍)早く、処理を終了しました。"
>3.65倍まで早く出来ましたが
自分の環境では4.24倍で
このマクロの奴だと8倍
vpxrgbでも6倍以上



MillkeyStars

リンク

2014/1/4(Sat) 02:55:43|NO.59136

利用目的がさっぱりわからないけど、処理によって、VRAM座標の割り出し計算を変えればいいと思うよ。
HSP の VRAM は、画面の左下ピクセルから右上ピクセルに向かって記録されているので。

pos 0,0 : などの左上から右下に向かう座標の場合は、上下(高さ)の座標を反対にする必要があるわけ。
画像データなどの独自記録の場合は、左下から右上のままで取得など。

できるだけ計算を少なくすれば高速化になるので、目的を確定してから考えるといいよ。



リンク

2014/1/4(Sat) 12:35:37|NO.59142

>とおりすがりさん
処理の内容は、46x1の画像から、rgbすべて255になっている場所を探すというものです。
とりあえず、アルゴリズムを最適化してみます。

>暇人さん
まさかそんなバグがあるとは・・・
修正していただきありがとうございます。
やはり新規命令となると処理に時間がかかるんですね。マクロで試してみます。

>MillkeyStarsさん
なるほど。そこら辺は全く考えていませんでした。
前に1度、独自の画像形式を作ったことがあるのですが、
VRAMが遅すぎて全く使い物にならなくて断念したことがあります。
あとで座標の割り出し計算を変えて試してみます。

今回の質問は解決しました。皆様、本当に有難うございました。



暇人

リンク

2014/1/4(Sat) 13:42:56|NO.59145

>rgbすべて255になっている場所
それなら
NO.59121のおまけがそのまま使えるかな

vpxrgb x,y if vpx_rgb=$ffffff {mes "白"}



暇人

リンク

2014/1/4(Sat) 15:09:29|NO.59149

1ドット毎に取得をマクロや命令でやろうとすると
効率悪いのでライン毎や矩形で処理した方が速度は稼げる

repeat 10 color rnd(255),rnd(255),rnd(255) boxf rnd(100) ,rnd(100) ,rnd(100) ,rnd(100) loop mref vramA,66 winx=ginfo_winx+(ginfo_sx-ginfo_winx) //サイズ可変ウィンドウに対応 winym=ginfo_winy-1+(ginfo_sy-ginfo_winy) //一番上のライン winx2=((winx*3+3)&-4) //VRAM横1ラインのサイズ repeat 100 //縦 loopy=(winym-cnt)*winx2 repeat 100 //横 memcpy rgb,vramA,3,0,loopy+cnt*3 if rgb=$ffffff {w++} //(ウィンドウ横サイズ*3)\4が0以外の時上二行の処理を下の一行で出来る // if (lpeek(vramA,loopy+cnt*3)&$ffffff)=$ffffff {w++} loop loop title "白の数="+w



リンク

2014/1/4(Sat) 16:25:13|NO.59150

>暇人さん

このサンプルを参考にプログラムを書いてみます。
本当にありがとうございました。



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