2017-12-13 10 views
0

のクラス全体をコピーするためのパフォーマンスペナルティがどのように悪いです、私が管理するメモリアロケータから派生するいくつかのクラスを持っているので、例えば:CUDA - 管理するメモリ

/* ---------管理https://devtalk.nvidia.com/default/topic/987577/-thrust-is-there-a-managed_vector-with-unified-memory-do-we-still-only-have-device_vector-cuda-thrust-managed-vectors-/

は------------それがcudaMallocManagedをやって、new演算子を上書きし、[今すぐ*/

class Cell : public Managed { 
    int a;float b;char c; // say ~50 fields 
} 

をキャストからですが、私が100,000セルオブジェクトの配列を持っていると言います、いくつかの大域関数に送りたいと思っています。この関数は、フィールドの小さな集合(例えば5〜10)だけを使用しますいくつかの計算を行います。

最も簡単な方法は、セルオブジェクトの配列全体を送信することです。しかし、多くの未使用データをコピーします。

より緊密なアプローチは、必要な5-10フィールドのみのデバイスアレイを割り当て、値をコピーしてグローバル関数に送信することです。グローバル関数本体にセルクラスの他のフィールドが必要な場合は、新しい配列を受け入れるためにシグニチャを書き直さなければならないため、少し面倒です。

私の質問 - 一般的に、最も簡単なアプローチを使用した場合のパフォーマンスのペナルティはどれくらいですか?

ありがとうございます!

+0

「配列全体を送信する」とはどういう意味ですか?管理対象メモリを使用している場合は、何も送信していません。ドライバとデバイスは、PCI-Eインターフェイスを介してデバイスによるアドホックアクセスを調整しています。 – talonmies

+0

"送信" - "Cell *"オブジェクトの配列をグローバル関数に渡します。私は知らない(と私はその実装に依存していると思う?)ボンネットの下で何が起こるか。 – danwanban

+0

また、引数としてカーネルへのポインタを渡すことは値渡しであり、基本的な構造体配列のコピーや転送は行われません。あなたは64ビットのアドレスを渡すだけです。 – talonmies

答えて

1

管理対象メモリが非常に扱われる方法depends on the compute capability of you device。 Pascal(6.x)以降では、アクセスされたページでのみ要求ページを発行します。

低いコンピューティング能力を持つデバイスは、アクセスされたメモリの量にかかわらず、まったくアクセスされるかどうかにかかわらず、管理されたメモリ全体を通常転送します。 ただし、explicitly declare the memory regions to transfer on a per-stream basis using cudaStreamAttachMemAsync()とすることができます。これにより、割り当てやデータ構造をまったく変更することなく、転送されるデータの量を制限することができます。