大きなデータセットのメモリ管理



LabVIEW 2018ヘルプ


発行年月: 2018年3月
製品番号: 371361R-0112
製品情報を参照

ダウンロード (Windowsのみ)


LabVIEW 2015ヘルプ
LabVIEW 2016ヘルプ
LabVIEW 2017ヘルプ
LabVIEW 2018ヘルプ
LabVIEW 2019ヘルプ

LabVIEWでは自動的にメモリ割り当てが処理されます。この処理は自動のため、データを安全に処理するように事前に注意を払う必要があります。つまり、頻繁にデータのコピーをとるようにします。プログラムで大きなデータのセットを扱う場合、大容量のデータコピーを頻繁に行うとメモリエラーが発生する可能性があります。メモリの問題を回避し、プログラムを最適化して大きなデータセットを処理するには、以下のガイドラインを使用します。

メモ  パフォーマンスおよびメモリをプロファイルウィンドウを使用して、VIの実行時間やメモリ使用量に関するデータの集録および表示を行うことができます。このウィンドウを使用して、メモリ障害に関与しているVIを確認します。

大規模データセットのコピーを削減する

LabVIEWはデータフロー言語であるため、1つのワイヤが2つに増えた場合などVIが追加データを必要とする場合は、データのコピーを作成します。LabVIEWは通常新しいコピーを作成する必要性を自動的に判断しますが、不明な場合は念のためにコピーを作成します。

メモ  LabVIEW Real-Timeモジュールを使用する場合、メモリのコピーによってリアルタイムアプリケーションの確定性が影響されます。

メモリの割り当て先を決定するにはバッファ割り当てを表示ウィンドウを使用します。このウィンドウでは、データコピーの保存に使用されるデータバッファを特定できます。

LabVIEWによって作成されるコピーの数を削減するには、以下のガイドラインを参考にしてください。

メモ  以下に示すヒントの中には、模範的なLabVIEWの設計方法に矛盾するものもあります。このため、これらは非常に大きなデータセットを扱う際にメモリの消費を減らす目的でのみ使用してください。
  • 可能な限り小さいデータタイプを使用します。たとえば、可能であれば倍精度浮動小数点数の代わりに16ビット整数を使用してください。
  • 単純な配列を使用します。波形またはダイナミックデータから処理するデータ配列を抽出すると、データの余分なコピーが作成されます。
  • 大きなブロックダイアラムまたはインラインサブVIを作成してオーバーヘッドを削減します。サブVIを呼び出すと、LabVIEWがデータのコピーを作成するため、サブVIは呼び出さないようにします。
  • サブVIを通るデータの経路を設定するには、すべてのブロックダイアグラム端子がケースストラクチャまたはループの外にあることを確認してください。端子がケースストラクチャまたはループ内にあると、より多くのデータコピーが生成されます。
  • 必要な場合以外は、ループを介したデータの経路は設定しないでください。ループを介してデータの経路設定を行う必要がある場合はシフトレジスタを使用します。トンネルを使用する場合、ループの反復ごとにデータコピーが作成されます。
  • 可能なかぎり、必須入力を使用します。デフォルト値の生成時にデータのコピーが作成されます。
  • フラットシーケンスストラクチャの代わりにIn Place要素ストラクチャを使用します。
ヒント  LabVIEWの新しいバージョンでは、旧バージョンよりも自動コピーが作成される状況が減りました。そのため、新しいバージョンでは大きいサイズのデータセットがより効率的に処理されます。

大きいサイズのデータセットを転送する

データコピーの作成を回避できない場合、次の対策として各コピーのサイズを小さくします。そのためには、データをある場所から別の場所に転送する際大きいサイズのデータセットをより小さいサイズのセットに分割します。この操作は、チャンク処理として知られる方法です。チャンク処理では、コピーを作成することによってメモリ使用量が増加することはありません。ただし、コピーによってスループットが低下するため、それらのコピーを最小化することは有意義です。以下の例で、この概念を具体的に説明します。

512 MBのデータをディスクへコピーする必要があるとします。このとき、1回の呼び出しですべてのデータを取得してディスクに保存することは可能です。ただし、発生するコピーの回数を1度に減らしても、元のデータともう1つの余分なコピーが転送されます。つまりLabVIEWに1 GBのメモリを要求することになります。この方法よりも、1度に500 KBのデータを取得してディスクへストリームするループを使用する方法が効率的です。メモリの使用量は、1 MB(元のデータ500 KBおよびコピー500 KB)まで小さくなります。これは、ほとんどのコンピュータでの制限範囲内に余裕を持って収まります。

またこの方法には、大きなメモリブロックの割り当てにかかる時間が大幅に節約される利点もあります。近年のコンピュータでは、250MBのデータをディスクにストリームする処理にかかる時間は15秒以下です。1度にすべてのデータをコピーする方法では、1 GBのRAMを割り当てるだけでこれだけの時間がかかる可能性があります。

サイズが大きいデータセットをストリームするか、RAID(Redundant Array of Independent Disks)にデータを保存する場合、バッファを使用せずにデータを転送して、データのコピーを減少して、データ転送速度を向上することができます。バッファを無効にするには、TRUEの値を「ファイルを開く/作成/置換」関数のバッファを無効入力に配線します。

大きいサイズのデータセットを表示する

多くの対話式アプリケーションでは、データを扱うべき唯一の操作はデータを他の人に表示することです。500万のデータポイントを表示する重要な理由があるかもしれませんが、このデータ量はほとんどの表示機能の範囲をはるかに超えています。LabVIEWグラフの平均は約300~1000ピクセル幅です。500万のポイントは、波形グラフ上で実際に参照可能な量の1000倍です。データデシメーションがこの問題の解決策です。

たとえば、グラフで非常に大きいサイズのデータセットの精密ピクセルバージョンを参照したいとします。500万のポイントバッファに単一のグリッチがある場合、プロットは1ピクセル幅の単一のスパイクのある水平ラインになるべきです。データが画面のピクセル幅よりも多くのサイクルを含む正弦波の場合、グラフは画像全体でエイリアスなしの固定帯域になるべきです。最大-最小デシメーションアルゴリズムは、これらの使用方法の両方の問題を解消します。

最大-最小デシメーションは、各デシメーション間隔の最大および最小データポイントを使用して、デシメーションを提供します。簡単なデシメーションは、デシメーション間隔のデータポイントに各デシメーション間隔の最初のポイントを使用します。簡単なデシメーションはエイリアスアーチファクトを発生させるため、時間が最も重視され、正確性が重要でない場合を除いて、使用するべきでありません。

最大-最小デシメーションを実装するには、最初にグラフのピクセル幅を決定します。グラフのプロット領域: サイズ: 幅プロパティを使用して、この値を検出します。アーチファクトを減少させるには、ピクセル幅ごとに最低2つのデシメーション間隔が必要であるため、グラフのピクセル幅を2で積算して、データを分割する標準の間隔数を取得します。この数値でデータの長さを除算し、最も近い整数に丸め込みます。これにより、デシメーションのチャンクサイズが得られます。各チャンクに対して、最大および最小ポイントを検出して、データセットで発生した順序と同様に並べます。最後のチャンクに残りのチャンクよりも少ないポイントが含まれていても問題でありません。問題は、ピクセル幅よりも小さく、コンピュータ画面上では参照できない点にあります。最大と最小のデータを一度に文字列化して、プロットします。画面上の各ピクセル幅は4ポイントです。これにより、隣接するピクセルに影響せずに、ピクセル幅のスパイクが発生することが可能です。最大/最小デシメーションは、固定帯域の高周波数の正弦波が生成されている状態で、データのピークを常に確認できることを保証します。これはグラフにより少ないデータがプロットされた状態で発生し、その結果速度が向上します。

以下の図で、最大-最小デシメーションを使用して左のデータを処理すると、右のようなグラフが生成されます。

大きいサイズのデータセットを保存する

キューまたはデータ値リファレンスを使用すると、大量のメモリを消費せずに大きいサイズのデータセットをメモリに保存できます。データを含む単一要素を含むキューを作成します。データにアクセスする度に要素をキューから解除します。これにより、プログラムの他の部分によって同時に要素にアクセスすることが阻止されます。データを操作した後に、要素を再度キューに入れます。転送の必要があるオブジェクトは、キューリファレンスのみです。LabVIEWは、キューの転送中に別のデータコピーを作成しません。キューに名前を付ける場合、「キュー取得」関数で名前を指定すると、いつでもキューのリファレンスを取得できます。複数のデータオブジェクトを作成する操作は複数のキューを作成するように簡単に行えます。

データ値リファレンスを使用して、別のデータコピーを作成せずにデータを保存することもできます。データ値リファレンスはキューよりも多少効果的ですが、タイムアウトオプションがありません。キューにデータを転送するかわりに、データのリファレンスを作成して、リファレンスを渡すことができます。データを操作するには、In Place要素ストラクチャを使用します。データ値リファレンス要素書き込み/読み取り境界ノードは、データ値リファレンスを入力として受け入れ、In Place要素ストラクチャ内でデータの処理を可能にし、元のメモリスペースにあるデータを置換します。

メモ  クラスプロパティダイアログボックスの継承ページで、LabVIEWクラスのメンバーVIのみがデータ値リファレンスをクラスに作成するように設定できます。

機能的グローバル変数を使用してメモリにサイズが大きいデータセットを保存することもできます。機能的グローバル変数によって一塊のデータの保存およびアクセスが可能になるため、大量のメモリを消費せずにデータを渡すことができます。データは初期化されていないシフトレジスタで保持されます。データの読み取り、書き込み、サイズ変更を行うには、配列関数を使用します。配列関数は固定された位置で操作を行うため、データのコピーを作成しません。この方法は、一般的にキューを使用する方法よりも低速です。



この記事は役に立ちましたか。

役に立たなかった