0

点群データとその背後にある四分木データ構造を操作してデータを処理するGUIアプリケーションがあります。使用しているポイント形式が最近変更されたため、新しい属性を保持するようにポイントクラスを変更する必要がありました。これにより、Pointオブジェクトのサイズが大幅に大きくなり、事実上、クワッドツリーのパフォーマンスが低下します。この属性の一部は、データの表示と処理には必要ありませんが、出力に保持する必要があります。これは、私のポイントクラスが現在どのように見えるかを大まかに示しています。

class Point {
public:
    /* ... */
private:
    /* Used data members */
    double x;
    double y;
    double z;
    double time;
    int attr1;
    int attr2;

    /* Unused data members */
    int atr3;
    double atr4;
    float atr5;
    float atr6;
    float atr7;
}

データがファイルからロードされると、ポイントはPoint *配列に格納され、クアッドツリーによって処理されます。同様に、それらが保存されると、ポイントの配列がクアッドツリーから渡され、ファイルに保存されます。クワッドツリーで使用しているPointオブジェクトは、ファイルに保存されているものとは異なりますが、ポイントの作成に使用するリーダーオブジェクトとライターオブジェクトを提供するライブラリを使用していることに注意してください。次に例を示します。

int PointLoader::load(int n, Point* points) {

    Point temp;
    int pointCounter = 0;

    /* reader object is provided by the library and declared elsewhere */        
    while (pointCounter < n && reader->read_point()) {
        temp = Point(reader->get_x(), reader->get_y(), reader->get_z(), /* ... */ )

        points[pointCounter] = temp;
        ++pointCounter;        
    }
    return pointCounter;
}

ここで、私の考えは、Pointクラスのサイズを縮小し、未使用の属性をハードドライブ上のPointDataと呼ばれる別のクラス(または構造体)に格納することです。これが必要なのは、通常、データがメモリに収まらず、キャッシュシステムが配置されているためです。これも、より小さなポイントオブジェクトの恩恵を受けます。したがって、例を考えると、次のようになります。

int PointLoader::load(int n, Point* points) {

    Point temp;
    PointData tempData;
    int pointCounter = 0;    

    while (pointCounter < n && reader->read_point()) {
        temp = Point(reader->get_x(), reader->get_y(), reader->get_z(), /* ... */ )
        pointData = (reader->get_attr3(), reader->get_attr4(), /* ... */)

        temp.dataHandle = /* some kind of handle to the data object */
        points[pointCounter] = temp;

        /* Save pointData to file to retrieve when saving points */

        ++pointCounter;        
    }
    return pointCounter;
}

次に、変更したポイントを保存するときに、dataHandle(ファイルオフセット?メモリマップト配列のインデックス?)を使用して、各ポイントのpointDataを取得し、ファイルに書き戻しました。

それは良い考えのように聞こえますか?これを達成するための最も賢明なアプローチは何でしょうか?

4

1 に答える 1

1

追加データを保存するためにマップされたファイルを使用することをお勧めします。これにより、メモリが不足している場合は自動的にディスクにフラッシュされ、RAM から削除されますが、十分なメモリがある場合は、ほとんどの場合 RAM に常駐します。

あなたのPointクラスでは、マップされたメモリ領域に直接ポインタを格納するよりも、ファイルにオフセットを格納する方が良いでしょう。ファイルを拡張するためにファイルを再マップする必要がある場合でも、オフセットは正しいからです (たとえばlseek()、自分でファイルを拡張する必要があります)。ファイルのサイズまでしかマッピングできません)。

このメカニズムはコーディングが非常に便利ですが、ファイル全体をマップするのに十分なアドレス空間が必要です。64 ビット アプリでは問題ありませんが、32 ビットで数百 MB 以上が必要な場合は問題になる可能性があります。ファイル内のデータの。もちろん、複数のファイルをマップおよびマップ解除できますが、より多くのコーディング作業が必要になり、パフォーマンスが低下します (ファイルのマップおよびマップ解除にはいくらかのコストがかかります)。

于 2012-03-22T13:13:39.790 に答える