|
|
2011/2/16(Wed) 17:31:06|NO.37142
500MB程度のテキストファイルをsdimした上でnoteloadしようとすると、
プログラムがエラーで停止します。
(HSP側でなく、Win側から報告するかと。)
解決法を示してください。
|
|
2011/2/16(Wed) 18:16:27|NO.37143
ご質問なされる御身分の御方がそのような口調で事をのたまうと
回答者一同恐縮してしまいかえって返信がつかないのではないかと思われます。
無礼を承知で申し上げますと、「教えてくださいよろしくお願いします」と書き添えたり
実際に動作するコードを張り付けたり、貴方のPCの搭載メモリ量などを提示したほうが
真っ当な返信がつくと思います。
|
|
2011/2/17(Thu) 08:33:48|NO.37148
普通はメモリにロードせんでファイルマッピングちゅうのおつかうんやけどな
|
|
2011/2/17(Thu) 14:03:59|NO.37150
>ファイルマッピング
もしかしてあれですか、
ファイルの読込インデックスと、読み込むサイズを指定する奴ですか。
なるほど。こういう場合に使うのですね。勉強になります。
ま、僕質問者じゃないんですけど(・ω・)
|
|
2011/2/17(Thu) 17:53:52|NO.37151
>ひらまる
多分ファイルマッピングについて誤解していると思います。
あなたが言っているのはbload命令のことではないでしょうか。
あなたもファイルマッピングについて自信がないようですし、
勝手に解釈せず、ちゃんとググるなりしましょう。
" http://www.google.co.jp/search?q=ファイルマッピング"
>yout
「示してください」と言われちゃ示さずにレスするわけにはいきませんね。
ファイルマッピング、別名メモリ・マップト・ファイルとは、
これは本来別の二つのプロセス間でメモリを共有するためのもので、
ファイルを仮想メモリにマップすることです。
その仮想メモリにアクセスして書き換えなどすると、
自動的にファイル本体が書き換えられます。
それを行えばバッファにファイルをロードし、
それをセーブするということをせずに済むので、
大きなサイズのファイルアクセスの効率化、
またこのnoteload問題を解決することができます。
質問は、せめて「示していただけませんか」ぐらいにしませんか。
参考 : http://itpro.nikkeibp.co.jp/article/COLUMN/20071107/286607/
|
|
2011/2/17(Thu) 19:15:18|NO.37152
言葉遣い失礼しました。
#runtime "hsp3cl"
sdim Primes,507044545
notesel Primes
noteload "prime10.txt"
mes Primes
stop
WinXp 32bit
Mem 1GB
ファイルマッピングの方法を教えてください。
|
|
2011/2/17(Thu) 20:27:02|NO.37155
すいません。さっきの参考URLは会員登録が必要でしたね。
参考(改) : http://tokyo.cool.ne.jp/chokuto/advanced/sharedmem.html
簡単に言うと、ファイルマッピングの流れはこんな感じです。
まずCreateFile関数で取得したファイルハンドルを
CreateFileMapping関数に渡し、ファイルマッピングオブジェクトを作成します。
成功したら、MapViewOfFile関数でマップし、マップされたアドレスが返されますので、
それを変数に割り当て、ファイルの編集を変数の編集により行います。
(メイン作業)
作業が終わり、ファイルを使う必要がなくなったら、
UnmapViewOfFile関数、CloseHandle関数で、アンマップ、ハンドル解放をします。
たぶん読んでもあまり伝わらないと思います。説明下手なもので。
細かいところ、分からないところは参考URLをみてください。
|
|
2011/2/17(Thu) 23:29:20|NO.37164
>ひよこさん
詳しい説明ありがとうございます。
つまりファイルマッピングというのは、
ハードディスクに存在するファイルを、
メモリ上に存在するデータのように扱う機能ということでしょうか。
いわゆる、「ファイルが使用中なのでアクセスできません」っていう奴ですか!!!
色々読んだり試したりしてみます。 ありがとうございました!
|
|
2011/2/17(Thu) 23:48:03|NO.37166
>ひらまるs
誠に申し上げにくいのですが、後半のほうちょっと違います。
前半(1〜5行目)は全くその通りです。
ただ、「ファイルが使用中なのでアクセスできません」については、
ファイルマッピングをした場合に出る場合があるというのに相違はないのですが、
これはファイルマッピングにかぎらず、他プロセスのファイルアクセス拒否の場合は出ます。
たとえばさっきの説明で、
ファイルマップ(CreateFileMapping〜UnmapViewOfFile関数)の部分をぬかしても、
CreateFileで他のプロセスがアクセスできないように第三引数で0を指定し、
排他ロックをかけるだけで、他プロセスのファイルアクセスを拒否できます。
また、ファイルマッピングをしたとしてもCreateFileで排他ロックをかけなければきっと
ダイアログは出ません。(試してないので間違ってたらすいません。)
つまり、「ファイルが使用中なのでアクセスできません」はファイルマッピングではなく
CreateFile関数での排他ロックによるものです。
|
|
2011/2/17(Thu) 23:53:51|NO.37167
思ったのですが、これにnote2arrayを使えば、
やはり大量のメモリあるいはディスクを使用することになるのですか?
|
|
2011/2/18(Fri) 01:36:25|NO.37168
>ひよこさん
たびたびすみません;
http://tokyo.cool.ne.jp/chokuto/advanced/function/CreateFile.html
を読んで理解しました。
ウィンドウズって、便利な機能がいっぱいついてるのに、それを使うのは大変なんですね。
>youtさん
はい、もちろんメモリを消費します。ディスクは消費しません。
ファイルマッピングが難しいのなら、(私も難しいです;)
私が↑で勘違いしたように、ファイルの一部だけを読み込むという方法もあります。
500Mbのファイルがどのようなものかはわかりませんが、
必要なときに必要な場所だけ読み書きすれば、メモリの代わりにCPUパワーを消費します。
つまり動作が遅くなるのですが、実装するのはとても簡単です。
noteloadの代わりにbloadを使用します。詳細についてはbloadのヘルプをご覧ください。
|
|
2011/2/18(Fri) 18:03:56|NO.37174
読み込みたいファイルは素数の一覧表で、
2 3 5 7 11 13
と続いています。これを配列変数として使用したいので、
使いたい場所だけと言うのがよくわかりません。
どうしたらいいのでしょうか。
|
|
2011/2/18(Fri) 18:36:00|NO.37175
>youts
素数の一覧表ですか。それは確かに配列にしないと扱いづらいですね。
大きなファイルを読み込む方法ではありませんが、
素数ファイルなら数値なので、バイナリにして保存したほうがよいと思います。
そうすれば、ファイルはとても小さくなると思います。
(もしすでになっていたら無視して結構です)
二つ聞きたいことがあります。
・素数はいくつまでで、全部でいくつですか。(だいたいでいいです。)
・話をはじめに戻すようで悪いのですが、
Windows側から報告されるエラーとはどのようなものでしょう。
よろしくお願いします。
|
|
2011/2/19(Sat) 10:29:29|NO.37176
いちいち言葉使いやらに指摘するやつがいるけどさどんだけ中学生なの?
いちいち反応する事ないだろ^^;
|
|
2011/2/19(Sat) 12:08:35|NO.37177
名前を変えても君が誰だかわかる人にはわかるので、顔を真っ赤にして荒らさないように。
|
|
2011/2/21(Mon) 17:46:43|NO.37222
だいぶ遅れて申し訳ありません。
素数一覧は10億まで、
エラーは、「ご迷惑をおかけします。問題が発生したため、hsp3cl.exeを終了します。」
と出て、下にエラー報告をする等のボタンが出るものです。
|
|
2011/2/22(Tue) 18:06:46|NO.37230
#runtime "hsp3cl"
sdim Primes,507044545
notesel Primes
noteload "prime10.txt"
mes Primes ;ココ
stop
試しに500MBのファイルを作ってこれを実行してみたところ、
おっしゃる通り、mesのところで、エラーが起きました。
いろいろいじってる途中にみつけましたが、
sdim Primes,507044545
をなくしてみてください。僕の環境ではそうしたらうまくいきました。
なぜこうなったかはわからなく、このまま使っていいとは思えませんが
うまくいったことはいったのでご報告します。
もっと大きく500MBちょうどにしたり、逆に小さく「7044545」などにしてもうまくいきました。
根拠は全然ありませんが、この「507044545」あたりの数字が悪いのかもしれません。
あなたの本物の素数ファイルと、こちらのダミーの500MBちょうどのファイルは
サイズも内容も全然違うのであなたの環境ではこうはいかないかもしれません。
まあ一応、sdim命令の行を無くしてみてください。
|
|
2011/2/22(Tue) 20:02:08|NO.37235
どうも極端に大きなメモリの開放か確保のタイミングで落っこちる・・・というのは、HSPではかなり前からあったように思います。
大きなデータを扱わせたプログラムが終了時に落っこちることがあったりしますので、解放になんか問題があるのかもしれません。
このスクリプトの場合、noteloadのタイミングでメモリを再確保しようとして開放か確保に失敗してるんではないでしょか。
|
|
2011/2/22(Tue) 20:19:22|NO.37236
へぇ。こういう問題は前からあったんですか。
やっぱり確保か解放かどちらかで失敗が起きているのだと思います。
でも、ファイルのサイズが大きいのが問題の根本なのはほとんど間違い無く、
ファイルマッピングは都合が悪いということなので、
僕は素数ファイルをバイナリファイルにすることを推奨します。
数値だという点で扱いやすく、配列にもしやすいです。
多少バイナリへの変換に手間はかかりますが、ハードディスクのためにもなります。
是非一度ご検討を。
|
|
2011/2/23(Wed) 01:16:14|NO.37247
問題が発生したため、hsp3cl.exe を終了します。 ご不便をおかけして申し訳ありません。
作業途中であった場合、その情報は失われた可能性があります。
この問題を Microsoft に報告してください。
結果はこうです。
またバイナリ化するにあたっても、こういった作業は不可欠なのではないでしょうか。
|
|
2011/2/23(Wed) 21:29:16|NO.37249
もちろんバイナリ化をしても確保、解放は必要ですが、サイズが小さくなりますから。
新しく、こんな方法はどうでしょう。
noteloadは読み込む場合、ファイルに合わせて変数を再確保しますが
bloadは変数に合わせてファイルを読み込みます。
もし、変数確保、解放の過程でエラーが起きていれば、
bloadを代わりに使うことによってきっと解決されます。
bloadとnoteloadは基本的にそこぐらいしか変わらないので、
多分ほかに不都合は起きません。
ちなみに僕の環境では改善されました。
成功することをお祈り致します。
|
|
2011/2/28(Mon) 00:42:23|NO.37289
すみません、また落ちました。
|
|
2011/2/28(Mon) 19:12:08|NO.37298
あまり解決へのヒントとはなりませんが、
OllyDbgなどを使った結果、mes命令の中(?)で
なぜかメモリ00000018番地に書き込みアクセスをしているからおちるようでした。
(何度も言うようですが、「僕の環境では」ですが)
このPrimes変数に対してstrmidやpoke,peekといった動作は問題ありませんが、
strlen関数、mes、dialog命令といったことをするとおちます。
strlenは文字数を数える場合、0x00という文字コードを探しているようです。
mes,dialogもきっと同様でしょう。
そして探しているうちにアクセス禁止領域に達し、エラーが出ると思われます。
strmid,poke,peekなどは、あらかじめ処理する文字数が決まっているので
0x00を探す必要はありません。
では、これを踏まえ、こんな方法だったらどうだっ。
素数表は507044545バイトなんですよね?
ではそのつぎに0x00を書き込めば。
poke Primes, 507044545, $00
これをmes命令の前にでも入れてください。
ちなみに僕の環境では改善されました。
成功することを心よりお祈り致します。
どうか成功してくれ。
|
|
2011/3/1(Tue) 16:30:45|NO.37316
質問に対する答えではありませんが…
バイナリ化するにあたっても、こういった作業は不可欠なのではないでしょうか。
これはつまるところ、今使っているtxtの素数一覧をバイナリに変換する、という考え方ですよね?
HSPの仕様に振り回されながら某所の素数一覧を使うぐらいなら、自分で計算して素数リストのバイナリをつくってしまうのはいかがですか?
(そもそもあの素数一覧は、プログラムから見て扱いやすいとは言えませんし)
試し割り法で1億までの素数を計算させて見ましたが、Core i7 920 2.66GHzで5時間ほどでした。
計算量は対象範囲の1.5乗に大体比例するので、1週間もあれば10億までの素数を計算できると思います。
1億までの素数一覧のバイナリはこちらです。
http://www1.axfc.net/uploader/Si/so/100844.bin
要素数5761455の1次元配列にbloadすれば使えます。
作成するのに使ったスクリプトも提示しておきます。
#runtime "hsp3cl"
#include "winmm.as"
max = 100000000 ; 素数を求める範囲の最大
dim prime, int(1.2*max/logf(max)) ; 素数を代入する配列
; int(1.2*max/logf(max)) ← 素数定理からアバウトに素数の個数を予測
prime(0) = 2, 3 ; 試し割りのルーチンで無限ループにならないように2と3だけ先に代入
num_of_prime = 2 ; 現在までの素数の個数
progress = 0 ; 進捗%
timeGetTime ; あとから経過時間を細かく計るためにgettimeではなくtimeGetTimeを使用
time_start = stat ; 開始時間
log = ""+gettime(0)+"/"+strf("%02d",gettime(1))+"/"+strf("%02d",gettime(3))+"\t"+strf("%02d",gettime(4))+":"+strf("%02d",gettime(5))+":"+strf("%02d",gettime(6))+"\t"+progress+"%\t"+time_start
mes log ; ログ表示
sdim log_buf, $1000 ; ログ保存用バッファ
log_buf += log+"\n" ; ログを追加
repeat max-3, 4 ; cntを4から最大値まで取るループ
candidate = cnt ; 素数かどうかの判定対象
repeat int(sqrt(candidate))-1, 2 ; cntを2から√(判定対象)まで取るループ
; int(sqrt(candidate)) ← √(判定対象)まで試し割りすれば十分
divisor = cnt ; 試し割りする除数
if candidate\divisor == 0 { ; 割り切れた場合
break ; 試し割り終了
} else { ; 割り切れなかった場合
if divisor == int(sqrt(candidate)) { ; √(判定対象)まで全て割り切れなかった場合
prime(num_of_prime) = candidate ; 素数を配列に代入
num_of_prime++ ; 素数の個数を更新
}
}
loop
if int(powf(double(candidate)/max,1.5)*100) > progress { ; 1%以上進捗した場合
progress++ ; 進捗%を更新
timeGetTime
log = ""+gettime(0)+"/"+strf("%02d",gettime(1))+"/"+strf("%02d",gettime(3))+"\t"+strf("%02d",gettime(4))+":"+strf("%02d",gettime(5))+":"+strf("%02d",gettime(6))+"\t"+progress+"%\t"+stat
mes log
log_buf += log+"\n"
}
wait 0
loop
timeGetTime
time_end = stat
log = "\t"+num_of_prime+" prime numbers in 1-"+max
mes log
log_buf += log+"\n"
ms = (time_end-time_start)\1000
sec = (time_end-time_start)/1000\60
min = (time_end-time_start)/1000/60\60
hour = (time_end-time_start)/1000/60/60
log = "\trequired "+strf("%02d",hour)+":"+strf("%02d",min)+":"+strf("%02d",sec)+"."+strf("%03d",ms)
mes log
log_buf += log+"\n"
bsave "prime.bin", prime, num_of_prime*4 ; 素数の配列を保存
notesel log_buf
notesave "prime.log" ; ログを保存
noteunsel
mes "\t\tcompleted."

| |
|
2011/3/1(Tue) 18:06:56|NO.37317
すごぉい 22Mbで済んでる!!
ところで初歩的な疑問ですが、素数のリストなど何に使うのでしょうか??
dim N, 5761455
bload "prime_100M.bin", N
FontSize = 20
font msgothic, FontSize
foreach N
redraw 0
pos 0, 1
gmode 0, ginfo_winx, ginfo_winy
gcopy 0
pos rnd( ginfo_winx + 50 ) - 50, 0
color rnd( 256 ), rnd( 256 ), rnd( 256 )
mes N( cnt )
title "" + N( cnt )
redraw 1
await 1
loop
|
|
2011/3/3(Thu) 18:52:09|NO.37359
>ひよこさん
Error 20 in Line 4 (poke Primes, 507044545, $00)
となってしまいました。
その後で匿名希望さんのprime_100M.binで同じことをしましたが、
同じエラーが出て、その行を削除すると動くようになりました。
|
|
2011/3/3(Thu) 19:49:38|NO.37362
つまりは、バイナリにしたら動いた=解決したってことですか?
pokeの意味はなかったようですいません。
|
|
2011/3/3(Thu) 21:03:26|NO.37363
エラーが出る理由としては、おそらくひよこさんの考え方が近いです。
件のtxtファイルが507,044,545bytesなので、きっかり507,044,545bytesの領域を確保して読み込むと、終端コードの0x00が入る場所がなくなってしまいます。
notesel primes
noteload "prime10.txt"
mes primes
と
exist "prime10.txt"
sdim primes, strsize+1
bload "prime10.txt", primes
mes primes
のどちらのやり方でも問題なく表示されることを確認しました。
(今10億までの素数一覧を計算中です。予想残り時間109時間…)
|
|
2011/3/3(Thu) 21:47:54|NO.37364
>>匿名希望s
sdim命令とはもともと、その文字数分のバッファを確保するとありますから、
内部では、それ+1分を確保していると思われます。
しかし、今回、サイズが極端に大きいせいか、0x00が書き込まれていないようなのです。
(strmid,peekではエラーが起きず、strlen,mesでは起きるところから考えて。)
ぼくもいろいろ考え、仮定をだし、実験してみて
どれも方法を提案しているのですが、
僕の環境ではうまくいくのに、youtさんの環境ではうまくいかないものも多いようで。。
話は変わりますが
素数の計算なら、 http://blog.livedoor.jp/dankogai/archives/51492290.htmlの
アルゴリズムはいいですよ。(HSPでなくC++で実行して確認しましたが。)
100時間以内にこれをHSPに変換できたら、ずっと速いです。
しかも、できるファイルの保存方法がとてもよいもので、
サイズに無駄が全然ありません。
(1,3,5,7,9,11…がそれぞれ素数かどうかをbooleanで表現してます。)
|
|
2011/3/3(Thu) 21:51:29|NO.37365
>匿名希望さん
自分の環境のせいでしょうか、Windowsのエラー方向のあれが出ました。
>ひよこさん
#runtime "hsp3cl"
exist "prime_100M.bin"
dim primes,5761455
bload "prime_100M.bin", primes
repeat
mes primes.cnt
loop
stop
で、きちんと表示されました。
でも、目標は巨大テキストの読み込みでもありますので、まだ解決チェックはしません。
|
|
2011/3/3(Thu) 21:55:59|NO.37366
>37364
すみません、簡単なCなら読めるのですが……
|
|
2011/3/3(Thu) 22:03:59|NO.37367
>>youts
僕の環境では、匿名希望さんのスクりでは、
上のは可能なんですが、下のはうまくいきません。
本当に環境によって、なんですかね。
あと、37365のスクリ、existの意味ないじゃないですか。
次の行で、dim strsize/4ぐらいしないと駄目じゃないですか?
|
|
2011/3/3(Thu) 22:19:06|NO.37368
dim strsize/4の意味がわかりません。sdimですか?
37316に使い方が書いてあったので、そうしたのですが……
existはやっぱり誤記です。
|
|
2011/3/3(Thu) 22:38:11|NO.37369
>>ひよこさん
sdim命令とはもともと、その文字数分のバッファを確保するとありますから、内部では、それ+1分を確保していると思われます。
これは間違いです。
マニュアルの「HSP3 文字列のひみつ(TIPS)」の、「文字列のしくみ」セクションに
ただし、256バイトのバッファを確保したとしても、255文字までしか使うことはできません。 最後に終了コード0を入れる場所が必要だからです。「sdim a,256」は、255文字+終了コード までは領域を確保するという意味になります。
とあります。
>>youtさん
巨大なtxtファイルの読み込みだけであれば、上でも何人かが挙げて下さってますが、ファイルマッピングを使うのがベストだと考えます。
素数の一覧であっても、工夫すればファイルマッピングで十分扱えます。
|
|
2011/3/3(Thu) 22:43:42|NO.37370
>>youtさん
いえ。どちらでもよいのです。
existは誤記だったということで別にいいのですが、一応解説させていただきます。
先にいっときます。電卓で計算してもらうとわかりますが、
strsize/4と5761455は等しいです。
ただ、existを実行しているのに何にも使ってないので、生かそうとしただけです。
prime_100M.binはバイナリファイルで、4byteで一数値を書き込んでいるので、
[素数の個数]*4(byte)がファイル全体のバイト数となります。
つまり、[ファイルサイズ(byte)]/4(byte)==[素数の個数] となるわけです。
existはファイルのバイト数をstrsizeにいれるわけですから、
strsize/4で素数の個数、すなわち確保すべきPrimeの要素数なわけです。
>>匿名希望さん
そうだったんですか。
sdimのHSP Document Libraryみたら「5000文字分の〜」と書いてあったので、
てっきり+1確保してるんだと思いました。
よくよく考えれば、確かに「5000文字ぶんのメモリをあらかじめ確保」には
0x00もはいっているともとれますね。
自分のミスを他人のミスのように言ってしまいすいませんでした。
|
|
2011/3/4(Fri) 00:45:24|NO.37373
>>ひよこさん
お気になさらず。
NO.37364を見てエラトステネスのふるいを思い出したので実装してみたところ、10億までの素数が11分でリストアップできました。
ひよこさんのおかげです。
ただ、boolean型に関してはHSPで扱いにくいので、bit単位ではなくbyte単位で処理しています。
途中の段階でそれぞれの数が素数かどうかのリストもできているのですが、上述の理由により1GBにも達してしまいました。
(奇数に絞り込むだけで半分までは縮小できますが…)
以下にソースを提示しておきます
#runtime "hsp3cl"
#include "winmm.as"
max = 1000000000
sdim primes, max+1
mes ""+gettime(0)+"/"+strf("%02d",gettime(1))+"/"+strf("%02d",gettime(3))+" "+strf("%02d",gettime(4))+":"+strf("%02d",gettime(5))+":"+strf("%02d",gettime(6))+"\tinitialization started."
timeGetTime
time_start = stat
repeat max-1, 2
poke primes, cnt, 1
await 0
loop
mes ""+gettime(0)+"/"+strf("%02d",gettime(1))+"/"+strf("%02d",gettime(3))+" "+strf("%02d",gettime(4))+":"+strf("%02d",gettime(5))+":"+strf("%02d",gettime(6))+"\tcalculation started."
repeat int(sqrt(max)), 2
divisor = cnt
if peek(primes,divisor) {
repeat max/divisor-1, 2
poke primes, divisor*cnt, 0
loop
}
await 0
loop
mes ""+gettime(0)+"/"+strf("%02d",gettime(1))+"/"+strf("%02d",gettime(3))+" "+strf("%02d",gettime(4))+":"+strf("%02d",gettime(5))+":"+strf("%02d",gettime(6))+"\tlisting started."
dim prime, int(1.2*max/logf(max))
repeat max-1, 2
if peek(primes,cnt) {
prime(num_of_prime) = cnt
num_of_prime++
}
await 0
loop
timeGetTime
time_end = stat
required_ms = time_end-time_start
required_sec = required_ms/1000
required_min = required_sec/60
required_hour = required_min/60
required_min \= 60
required_sec \= 60
required_ms \= 1000
mes ""+gettime(0)+"/"+strf("%02d",gettime(1))+"/"+strf("%02d",gettime(3))+" "+strf("%02d",gettime(4))+":"+strf("%02d",gettime(5))+":"+strf("%02d",gettime(6))+"\tcompleted."
bsave "prime_byte.bin", primes
bsave "prime_int.bin", prime, num_of_prime*4
mes ""+num_of_prime+" prime numbers in 1-"+max
mes "required "+strf("%02d",required_hour)+":"+strf("%02d",required_min)+":"+strf("%02d",required_sec)+"."+strf("%03d",required_ms)
sdimで(max+1)bytes確保した変数に"prime_byte.bin"を読み込み、peek(読み込んだ変数名,素数かどうか判定したい数)とやると、素数なら1/合成数なら0が返ります。
"prime_int.bin"は、NO.37316でUPしたものと同じ形式で、4bytes毎にint型で素数が記録されています。
NO.37370でひよこさんが解説して下さっている様に、existの後dimで要素数(strsize/4)の1次元配列を確保して読み込めば使えます。

| |
|
2011/3/5(Sat) 17:29:20|NO.37412
37373を使って、ファイルを作ってそれをbloadしようかと思います。
ですが、37373を3時間ほど動かしても、終わりません。
|
|
2011/3/5(Sat) 21:11:36|NO.37426
"prime_byte.bin"と"prime_int.bin"の詰め合わせcabファイルです
http://www1.axfc.net/uploader/P/so/86980
ちなみに
ですが、37373を3時間ほど動かしても、終わりません。
では、何がどうなっているのかわかりません。
・CPU/メモリ容量
・表示はどこで止まっているのか
を書いてもらえれば、原因や対処法がわかるかもしれません。
|
|
2011/3/5(Sat) 21:15:31|NO.37428
>>匿名希望さん
メモリ量については、このスレッドの上のほう、37152にかいてありますよ
|
|
2011/3/6(Sun) 00:44:17|NO.37435
OS
WinXp Service Pack 3
CPU
Pentium 4 320GHz 319GHz
RAM
物理 0.99GB
コミットチャージ 2.44GB
環境上記のとおりです。
停止時の表示はcalculation started.です。
また、sdim単体の時間も合わせて計測しましたが、40秒ほどかかっています。
|
|
2011/3/6(Sun) 04:13:09|NO.37442
NO.37152は見落としていました。
すみません。
一言で言うとメモリ不足です。
1GB近くのメモリ領域を確保しようとしているのにRAMが1GBしかないので、HDDから1GBのメモリ領域を確保(ページング)していると思われます。
HDDの読み書き速度はRAMと比較にならないほど遅いので、それがパフォーマンスの低下につながっています。
結論としては、NO.37373で提示したスクリプトをそちらの環境で動かすのは諦めていただいた方が良いと思います。
ところでNO.37426でUPしたファイル(の内"prime_int[_1G].bin")は利用できましたでしょうか?
(上述の理由により、"prime_byte[_1G].bin"を利用するのは避けていただいた方が良いと思います。)
|
|
2011/3/7(Mon) 17:11:43|NO.37471
37426のprime_int_1G.binは使えました。ありがとうございます。
ですが、HSPで1bit単位のメモリ管理はできないのでしょうか。
それができれば、速度がもっと上がると思うのですが……
|
|
2011/3/7(Mon) 18:11:41|NO.37473
利用できたようでよかったです。
ですが、HSPで1bit単位のメモリ管理はできないのでしょうか。
それができれば、速度がもっと上がると思うのですが……
実はNO.37373のスクリプトの素数判定部分をbit単位で実装してみたのですが、処理時間が3倍以上にもなってしまいました。
(奇数のみに絞り込んでの判定でも、2倍近くかかる計算になります。)
メモリ読み書きの命令は、最小でもpeekとpokeの1byte単位なので、無駄なビット演算が増えてしまうのが原因です。
消費メモリを1/8に節約できるのは大きいですが、高速処理には向きません。
(もちろん、メモリの少ない環境ではページングが発生しない分、速度の上昇が見込まれますが。)
|
|
2011/3/7(Mon) 18:25:42|NO.37474
>37473
メモリの読み書き(特に読み)の最小単位をAPIあるいはDLLや機械語でbyteにできませんか?
|
|
2011/3/7(Mon) 18:56:28|NO.37476
もうバイナリにして、配列を扱う必要もなくなったので、
ファイルマッピングのほう、検討していただいたほうが早いかと。
|
|
2011/3/7(Mon) 19:13:31|NO.37478
>>youtさん
byte単位なら、peek,pokeでいいんじゃないんですか?
|
|
2011/3/8(Tue) 00:48:54|NO.37489
>37476
ファイルマッピングなら巨大なファイルであっても
読み込みだけなら何とかなるのでしょうか。
速度が心配です。
>37478
p2=0〜 : バッファのインデックス(Byte単位)
解説
変数に保存されたデータメモリ上の任意の場所にある1バイト(8bit)の内容を数値として返します。
関数の戻り値は、0〜255までの整数値になります。
|
|
2011/3/8(Tue) 18:23:15|NO.37497
>>youtさん
>>37476
>ファイルマッピングなら巨大なファイルであっても
>読み込みだけなら何とかなるのでしょうか。
>速度が心配です。
読み込みも書き込みも可能です。
速度は、これ以上速い方法はないだろう、というぐらい速いです。
500MBあっても、1秒くらいで動きます。(僕のでは)
>>37478
>p2=0〜 : バッファのインデックス(Byte単位)
>解説
>変数に保存されたデータメモリ上の任意の場所にある1バイト(8bit)の内容を数値として返します。
>関数の戻り値は、0〜255までの整数値になります。
だからなんですか?
ちゃんと
「メモリの読み書き(特に読み)の最小単位を"基本命令だけ"でbyteにでき」てるじゃないですか。
|
|
2011/3/8(Tue) 21:46:40|NO.37505
OpenHSPのほうでテストしてみました。
noteloadとmesで落ちるのは単純にメモリ不足ではないでしょうか。
OpenHSPの実装を見る限りmesで文字列を出力するには一時的に文字列の3倍以上のメモリが必要です。
32bitプログラムで利用可能なメモリは普通2GB程度なので500MBの3倍となると
他での消費やメモリ管理でのオーバーヘッドもあわせるとかなり厳しいかと思います。
|
|
2011/3/9(Wed) 04:39:18|NO.37507
>37497
先ほどのメモリのページングのときにだいぶ遅くなると聞いたのですが、
その辺は大丈夫なのですね。
それから、質問が悪かったです。
「HSPで変数に保存されたデータメモリ上の任意の場所にある1byteの内容を数値として返す
方法はありませんか?」
|
|
2011/3/9(Wed) 06:54:34|NO.37509
> HSPで変数に保存されたデータメモリ上の任意の場所にある1byteの内容を数値として返す
のと
> 変数に保存されたデータメモリ上の任意の場所にある1バイト(8bit)の内容を数値として返します。
の違いがわかりません。
1byteならpeekとpokeでインデックス(場所)を指定することで可能です。
1bitの間違いでしょうか?
> メモリの読み書き(特に読み)の最小単位をAPIあるいはDLLや機械語でbyteにできませんか?
bitだと仮定した場合、おそらく不可能です。
Win32APIどころかx86アーキテクチャにも、メモリ上の特定ビットだけを読み取(書き換え)る命令は(私の知る限り)ありません。
読み取り:1byte読み出し→ビットマスク
書き換え:1byte読み出し→ビット演算→元のアドレスに書き込み
といった手順を踏むことになります。
他言語に詳しくないため、NO.37373で紛らわしい書き方をしてしまいましたが、そのせいで勘違いさせてしまったとしたら済みません。
大抵の言語では、bool型のサイズは1byteないし(32bit処理系の場合)4byteになっているようです。
32bit処理系の環境では、32bit(4byte)単位のメモリアクセスが一番効率が良いと言われています。
1bit単位の読み書きアクセスを実装しても、余計なオーバーヘッドが生じる分処理効率は上がらないでしょう。
(繰り返しますが、物理メモリの少ない環境では速度向上が見込まれるかもしれません。)
あと横レスですが
> 先ほどのメモリのページングのときにだいぶ遅くなると聞いたのですが、その辺は大丈夫なのですね。
ページングとファイルマッピングは仕組みからして全然違います。
少しアバウトな言い方をすると、必要なメモリ領域をHDD領域に依存するのがページングで、最小限の変更点をメモリ上に置いてキャッシュしながらHDDにアクセスするのがファイルマッピングです。
必要な関数は既にひよこさんが答えてくださっているので、興味があるなら実際に試してみるのが一番だと思います。
ここで処理速度について質問しても、実際の処理については何も身につきませんので。
|
|
2011/3/9(Wed) 15:20:59|NO.37514
>37509
1bitです。すみません。
メモリマップトファイルを実装してみましたが、動きません。
最初のfailed.が表示されるようです。
#runtime "hsp3cl"
#include "kernel32.as"
name = "prime_byte_1G.bin"
exist name
textsize =strsize
onexit *OnAppExit
CreateFile name,8,0,0,3,1,0
hfile =stat
CreateFileMapping hfile,0,2,0,0,0
hmapobj =stat
if hmapobj =0{
mes "failed."
stop}
GetLastError
if (stat =183){
mes "failed."
stop}
MapViewOfFile hmapobj,4,0,0,0
lpdata =stat
dupptr isprime,lpdata,textsize,2
mes peek(isprime,53)
stop
*OnAppExit
UnmapViewOfFile lpdata
if hmapobj{
CloseHandle hmapobj
}
end
|
|
2011/3/9(Wed) 18:28:59|NO.37517
CreateFileへの第二引数が不正です。
GENERIC_READは$80000000,GENERIC_WRITEは$40000000です。
|
|
2011/3/10(Thu) 02:56:55|NO.37524
#runtime "hsp3cl"
#include "kernel32.as"
name = "prime_byte_1G.bin"
exist name
textsize =strsize
onexit *OnAppExit
CreateFile name,0x80000000,0,0,3,1,0
hfile =stat
CreateFileMapping hfile,0,2,0,0,0
hmapobj =stat
if hmapobj =0{
mes "failed."
stop}
GetLastError
if (stat =183){
mes "failed."
stop}
MapViewOfFile hmapobj,4,0,0,0
lpdata =stat
dupptr isprime,lpdata,textsize,2
mes peek(isprime,99999989)
stop
*OnAppExit
UnmapViewOfFile lpdata
if hmapobj{
CloseHandle hmapobj
}
end
これできちんと動きました。
皆さんありがとうございます。
また最初の質問も37505で解説されています。
ありがとうございました。
|
|