2016-08-01 13 views
2

私は32ビットOSGEarthプロジェクトで作業しています。ここでは、選択したイメージを1つの大きなイメージにモザイク化する必要があります。 64ビットへの切り替えはオプションではありません。32ビット以上のヒープメモリを割り当てることができます

イメージは256x256タイルの集合としてメモリに格納されます。 問題は、ユーザーが多くのタイルから1つのイメージを作成しようとしたときに、OSGEarthが内部的に32ビットシステムより多くのメモリを割り当てようとしたときに発生します。

私はこの制限を回避するために、それぞれ1025バイトのサイズのデータ​​をいくつか割り当てます。その後、1025バイト目は次のチャンクの先頭に「ポイント」し、最後のバイトはnullptrになります。

これは私が現在、(私は将来的にはより多くを割り当てる予定)やっているものです:私は実際に起こっている起こることを期待していたらどう

unsigned char* start = new unsigned char[1025]; 
unsigned char** head = &start; 
unsigned char** tail = head + 1025; 

for (unsigned int i = 0; i < 3; ++i) 
{ 
    auto c = new unsigned char[1025]; 
    *tail = &c[0]; 
    tail = &c + 1025; 
} 

memset(head, 'C', 1025 * 4); 

はしかし、私はいくつかの予約を持っています。メモリは本当に1つの連続したブロックに割り当てられていますか?もしそうでなければ、私のmemsetは割り当てられていないデータを書き込んでいます。これは悪い可能性があります。

32ビットの制限はありますか?

+4

* 64ビットに切り替えることはオプションではありません。* - 石から血を搾り取ることはできません。多分それを再考する時でしょうか? – PaulMcKenzie

+0

"OSGEarth [...]が32ビットシステムよりも多くのメモリを割り当てようとすると、問題が発生します。"あなたは3GiB以上の意味ですか? – ysdx

+0

私は地球の高解像度地図を使って作業しています。画像そのものは小さくなる傾向がありますが、OSGが求めているデータは実際にはギガバイト単位で増加しています。 – Acorn

答えて

5

メモリは本当に1つの連続したブロックに割り当てられていますか?

保証はありません。あなたが新しいものを呼び出すたびに、あなたは記憶のどこにいても記憶のブロックを与えることができます。あなたが効果的にやっていることは、リンクリストを作成することであり、リンクリストは連続していません。

連続したメモリが必要で、32ビットに制限されている場合は、本当に何もできません。例外(例外が発生している場合)をキャッチして、イメージが作成されるべきものであることをユーザーに報告することができます。

+0

それは私が恐れていたものです。 osg :: Imageを使って作業すると、私はそれをデータのまとまりに渡し、データが連続していないことを伝えることはできません。会議の時間! – Acorn

0

サンプルコードでは、bad_alloc例外をスローすると、newの結果はチェックされません。

最終画像がメモリよりも大きくなりたい場合はエラーが発生しますか?最終的な画像をメモリに固定しておく必要がありますか?タイルを一緒にステッチするのにどのようなアルゴリズムを使用しますか?

32MBのRAMを搭載した組み込みシステムでも同様の問題が発生しました。可能な解決策は、最終画像をディスク上のファイルとして保持し、次のタイルをステッチするのに十分な情報だけをメモリに保持することである。メモリに1つの巨大ブロックを割り当てるだけではなく、ディスクサイズによって制限され、32ビットのアドレス空間ではなくなります(もちろん、パフォーマンスが低下します)。

+3

'new'は' nullptr'を返しません。例外をスローします。 – milleniumbug

+0

私はこれについて考えました.2つの画像をつなぎ合わせています。それはうまくいくかもしれませんが、別の問題が生じます。後で、イメージがスケールアップされます(私たちは高解像度の地図を使って作業しています)。 限られたメモリ容量で、画像を望みどおりに拡大することはできないと私は考えています。 – Acorn

+0

画像の縮尺を調整できないのはなぜですか?または、最初にタイルをスケーリングしてからステッチしますか?スケーリングは線形演算です。 – ilya1725

1

Windowsの場合、64ビットWindowsで実行されていても、32ビット実行可能ファイルはデフォルトで2GBに制限されています。 32ビットアプリケーションで最大4GBまで使用できるようにするには(特に64ビットWinで実行している場合)、/LARGEADDRESSAWARE MSVCリンカフラグを設定します(もちろん、 "認識できない"プログラムが "否定"例えばポインタ/整数変換が含まれている場合)。

このフラグは既存の実行可能ファイルでも変更できます。これはEXEヘッダーのマスクフラグです。 dumpbinで確認し、editbinで変更することができます(両方ともMSVCが付属しています)。例:http://gisgeek.blogspot.de/2012/01/set-32bit-executable-largeaddressaware.html

関連する問題