GPU を使用したシミュレーションの高速化
GPU ベースの System object™ は外観も動作も、Communications Toolbox™ 製品の非 GPU ベースの System object とよく似ています。重要な違いは、アルゴリズムが CPU ではなくグラフィックス処理装置 (GPU) で実行されるという点です。GPU を使用するとシミュレーションを高速化できる場合があります。
GPU は、大量データの処理と高負荷計算の実行に威力を発揮します。大量データ処理とは、シミュレーションにおいて GPU のスループットを最大限に活用する 1 つの手法です。GPU が一度に処理するデータ量は、GPU ベースの System object の入力に渡されるデータのサイズによって異なります。このため、このデータ サイズを最大にするには、複数のデータ フレーム処理という方法をとります。
1 つの GPU ベースの System object を使用して、複数のデータ フレームを同時に、つまり並行して処理できます。これは、標準の System object の実装方法とは異なる実装です。GPU ベースの System object では、オブジェクト関数の 1 回の呼び出しでオブジェクトが処理するフレーム数は、オブジェクトのプロパティで暗黙的に指定されるか、オブジェクトの NumFrames
プロパティを使用して明示的に宣言されます。
GPU ベースの System object に MATLAB® 配列を渡すには、CPU から GPU に初期データを転送しなければなりません。その後、GPU ベースの System object により計算が実行され、出力データが CPU に返されます。このプロセスでレイテンシが発生します。gpuArray
(Parallel Computing Toolbox) の形式でデータを GPU ベースの System object に渡す場合、オブジェクトはデータ転送によるレイテンシを課されません。このため、入力として gpuArray
を提供すると、GPU ベースの System object の実行速度は向上します。
一般的に、シミュレーションでは CPU と GPU 間のデータ転送は最小限に抑えるようにします。詳細については、GPU での配列の確立 (Parallel Computing Toolbox)を参照してください。
GPU ベースの System object の作成
Communications Toolbox 製品の System object は comm
パッケージにあり、次のように作成されます。
H = comm.<オブジェクト名>
たとえば、ビタビ復号化器 System object は次のように作成します。
H = comm.ViterbiDecoder
System object に対応する GPU ベースの実装が存在する場合は comm.gpu
パッケージにあり、次のように構築されます。
H = comm.gpu.<オブジェクト名>
たとえば、GPU ベースのビタビ復号化器 System object は次のように作成します。
H = comm.gpu.ViterbiDecoder
利用可能な GPU ベースの実装のリストについては、System object の GPU 配列のサポート リストを参照してください。
GPU ベースの System object を使用した複数のデータ フレームの処理
1 つの GPU System object™ を使用して、複数のデータ フレームを同時に処理できます。LDPC 復号化器など GPU ベースの一部の System object は、オブジェクト プロパティからフレーム数を推定できます。ビタビ復号化器など GPU ベースの他の System object には、入力データに含まれるフレーム数を定義する NumFrames
プロパティが組み込まれています。
まず、GPU ベースの LDPC 復号化器 System object™ を使用して 2 つのデータ フレームを同時に処理します。ParityCheckMatrix
プロパティによってフレーム サイズが決まります。フレーム サイズと入力データ ベクトルの長さによって、LDPC 復号化器オブジェクトによって処理されるフレームの数が決まります。
numframes = 2; ldpcEnc = comm.LDPCEncoder; ldpcGPUDec = comm.gpu.LDPCDecoder; ldpcDec = comm.LDPCDecoder; msg = randi([0 1],32400,2); for ii=1:numframes encout(:,ii) = ldpcEnc(msg(:,ii)); end % Single ended to bipolar (for LLRs) encout = 1-2*encout; % Decode on the CPU for ii=1:numframes cout(:,ii) = ldpcDec(encout(:,ii)); end % Multiframe decode on the GPU gout = ldpcGPUDec(encout(:)); % Check equality isequal(gout,cout(:))
ans = logical
1
次に、GPU ベースのビタビ復号化器 System object の NumFrames
プロパティを使用して、複数のデータ フレームを処理します。ビタビ復号化器では、システムのフレーム サイズをオブジェクトのプロパティから推定することはできません。代わりに、ビタビ復号化器オブジェクトの NumFrames
プロパティを使用して、入力データに含まれるフレーム数を定義しなければなりません。
numframes = 10; convEncoder = comm.ConvolutionalEncoder( ... TerminationMethod="Terminated"); vitDecoder = comm.ViterbiDecoder( ... TerminationMethod="Terminated");
NumFrames
プロパティを使用して、GPU ベースのビタビ復号化器 System object を作成します。
vitGPUDecoder = comm.gpu.ViterbiDecoder( ... TerminationMethod="Terminated", ... NumFrames=numframes); msg = randi([0 1],200,numframes); for ii=1:numframes convEncOut(:,ii) = 1-2*convEncoder(msg(:,ii)); end % Decode on the CPU for ii=1:numframes cVitOut(:,ii) = vitDecoder(convEncOut(:,ii)); end % Decode on the GPU gVitOut = vitGPUDecoder(convEncOut(:)); % Check equality isequal(gVitOut,cVitOut(:))
ans = logical
1
gpuarray 入力を使用した GPU ベースの System object へのデータの受け渡し
この例では、畳み込み符号化率 1/2 の 16-PSK 変調データを AWGN チャネル経由で送信し、受信データを復調および復号化して受信データのエラー レートを評価します。この実装では、GPU ベースのビタビ復号化器 System object™ を使用して複数の信号フレームを 1 回の呼び出しで処理し、gpuArray
(Parallel Computing Toolbox)オブジェクトを使用して GPU ベースの System object との間でデータをやり取りします。
PSK 変調と復調、畳み込み符号化、ビタビ復号化、および AWGN 用の、GPU ベースの System object を作成します。エラー レート計算用の System object を作成します。
M = 16; % Modulation order numframes = 100; gpuconvenc = comm.gpu.ConvolutionalEncoder; gpupskmod = comm.gpu.PSKModulator(M,pi/16,BitInput=true); gpupskdemod = comm.gpu.PSKDemodulator(M,pi/16,BitOutput=true); gpuawgn = comm.gpu.AWGNChannel( ... NoiseMethod='Signal to noise ratio (SNR)',SNR=30); gpuvitdec = comm.gpu.ViterbiDecoder( ... InputFormat='Hard', ... TerminationMethod='Truncated', ... NumFrames=numframes); errorrate = comm.ErrorRate(ComputationDelay=0,ReceiveDelay=0);
ビタビ復号化アルゴリズムの計算量ゆえに、信号データの複数のフレームを GPU に読み込んで 1 回の呼び出しで処理すると、シミュレーション全体の時間を短縮できます。この実装を有効にするために、GPU ベースのビタビ復号化器 System object には NumFrames
プロパティが含まれています。外部 for
ループを使用してデータの個々のフレームを処理する代わりに、NumFrames
プロパティを使用して GPU ベースのビタビ復号化器 System object を構成し、複数のデータ フレームを処理します。バイナリ データ フレームの numframes
を生成します。GPU ベースの System object による処理のためにデータ フレームを効率的に管理するには、送信データ フレームを gpuArray
オブジェクトとして表現します。
numsymbols = 50; rate = 1/2; dataA = gpuArray.randi([0 1],rate*numsymbols*log2(M),numframes);
エラー レート オブジェクトは gpuArray
オブジェクトやマルチチャネル データをサポートしていないため、関数gather
(Parallel Computing Toolbox)を使用して GPU から配列を取得し、for
ループ内でデータの各フレームのエラー レートを計算しなければなりません。for
ループ内で GPU ベースの符号化、変調、AWGN、および復調を実行します。
for ii = 1:numframes encodedData = gpuconvenc(dataA(:,ii)); modsig = gpupskmod(encodedData); noisysig = gpuawgn(modsig); demodsig(:,ii) = gpupskdemod(noisysig); end
GPU ベースのビタビ復号化器は、for
ループなしでマルチフレーム処理を実行します。
rxbits = gpuvitdec(demodsig(:)); errorStats = errorrate(gather(dataA(:)),gather(rxbits)); fprintf('BER = %f\nNumber of errors = %d\nTotal bits = %d', ... errorStats(1), errorStats(2), errorStats(3))
BER = 0.009800 Number of errors = 98 Total bits = 10000
MATLAB System ブロックでの GPU ベースの System object のサポート
実装で MATLAB System (Simulink) ブロックを使用している場合、以下の GPU ベースの System object を含めることができます。
comm.gpu.AWGNChannel
comm.gpu.BlockDeinterleaver
comm.gpu.BlockInterleaver
comm.gpu.ConvolutionalDeinterleaver
comm.gpu.ConvolutionalEncoder
comm.gpu.ConvolutionalInterleaver
comm.gpu.PSKDemodulator
comm.gpu.PSKModulator
comm.gpu.TurboDecoder
comm.gpu.ViterbiDecoder
GPU System object は [インタープリター型実行]
を使用してシミュレーションしなければなりません。このオプションはブロック マスクで明示的に選択しなければなりません。既定値は [コード生成]
です。
関連するトピック
- コード生成と高速化のサポート
- GPU 計算の要件 (Parallel Computing Toolbox)