このページは前リリースの情報です。該当の英語のページはこのリリースで削除されています。

GPU を使ったシミュレーションの高速化

GPU ベースの System object

GPU ベースの System object は外見も動作も Communications Toolbox™ の他の System object とほぼ同様です。重要な違いは、アルゴリズムが CPU ではなくグラフィックス プロセシング ユニット (GPU) で実行されるという点です。GPU を使用するとシミュレーションを高速化できる場合があります。

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 ベースの実装の一覧を表示するには MATLAB® コマンド ラインで help comm と入力し、[GPU Implementations] をクリックします。

GPU の使用に関する一般的なガイドライン

グラフィックス プロセシング ユニット (GPU) は大量データの処理と高負荷計算の実行に威力を発揮します。大量データ処理とは、シミュレーションにおいて GPU のスループットを最大限に活用する 1 つの手法です。GPU が一度に処理するデータ量は、GPU System object の入力に渡されるデータのサイズによって異なります。このため、このデータ サイズを最大にするには、複数のデータ フレーム処理という方法をとります。

1 つの GPU System object を使用して、複数のデータ フレームを同時に、つまり並行して処理できます。これは多くの標準 (つまり非 GPU) の System object の実装方法とは異なります。GPU System object では、オブジェクト関数の 1 回の呼び出しでオブジェクトが処理するフレーム数は、オブジェクトのプロパティで暗黙的に指定されるか、オブジェクトの NumFrames プロパティを使用して明示的に宣言されます。

BPSK 変調とターボ符号化を使用した送信と復号化

この例では、ターボ符号化されたデータのブロックを BPSK 変調された AWGN チャネル経由で送信する方法を示します。次に、反復ターボ復号化器を使用して復号化し、誤りを表示する方法を示します。

結果を繰り返し可能にするために、ノイズ変数を定義し、フレーム長を 256 に設定し、乱数ストリーム プロパティを使用します。

noiseVar = 4; frmLen = 256;
s = RandStream('mt19937ar', 'Seed', 11);
intrlvrIndices = randperm(s, frmLen);

ターボ符号化器 System object を作成します。構成畳み込み符号のトレリス構造体は poly2trellis(4, [13 15 17], 13) です。InterleaverIndices プロパティは、符号化器でオブジェクトが入力ビットを並べ替えるために使用するマッピングを、整数の列ベクトルとして指定します。

turboEnc = comm.TurboEncoder('TrellisStructure', poly2trellis(4, ...
      [13 15 17], 13), 'InterleaverIndices', intrlvrIndices);

BPSK 変調器 System object を作成します。

bpsk = comm.BPSKModulator;

AWGN チャネル System object を作成します。

channel = comm.AWGNChannel('NoiseMethod', 'Variance', 'Variance', ...
      noiseVar);

GPU ベースのターボ復号化器 System object を作成します。構成畳み込み符号のトレリス構造体は poly2trellis(4, [13 15 17], 13) です。InterleaverIndicies プロパティは、符号化器でオブジェクトが入力ビットを並べ替えるために使用するマッピングを、整数の列ベクトルとして指定します。

turboDec = comm.gpu.TurboDecoder('TrellisStructure', poly2trellis(4, ...
      [13 15 17], 13), 'InterleaverIndices', intrlvrIndices, ...
      'NumIterations', 4);

誤り率 System object を作成します。

errorRate = comm.ErrorRate;

シミュレーションを実行します。

for frmIdx = 1:8
 data = randi(s, [0 1], frmLen, 1);
 encodedData = turboEnc(data);
 modSignal = bpsk(encodedData);
 receivedSignal = channel(modSignal); 

復号化のために受信信号を対数尤度比に変換します。

receivedBits  = turboDec(-2/(noiseVar/2))*real(receivedSignal));

元のデータと受信データを比較して、誤り率の結果を計算します。

errorStats = errorRate(data,receivedBits);
end
fprintf('Error rate = %f\nNumber of errors = %d\nTotal bits = %d\n', ...
errorStats(1), errorStats(2), errorStats(3))

GPU を使用した複数のデータ フレームの処理

この例では、LDPC 復号化器 System object を使用して 2 つのデータ フレームを同時に処理する方法を示します。ParityCheckMatrix プロパティがフレーム サイズを決定します。オブジェクトが処理するフレーム数は、フレーム サイズと入力データ ベクトルの長さで決定されます。

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(:))

NumFrames プロパティを使用した複数のデータ フレームの処理

この例では、GPU ベースのビタビ復号化器 System object の NumFrames プロパティを使用して、複数のデータ フレームを処理する方法を示します。ビタビ復号化器では、システムのフレーム サイズをオブジェクトのプロパティから推定することはできません。このため、NumFrames プロパティにより入力データに含まれるフレーム数が定義されます。

numframes = 10;
 
convEncoder = comm.ConvolutionalEncoder('TerminationMethod', 'Terminated');
vitDecoder = comm.ViterbiDecoder('TerminationMethod', 'Terminated');
 
%Create a GPU Viterbi Decoder, using NumFrames property.
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(:));
 
isequal(gVitOut,cVitOut(:))

gpuArray と標準の MATLAB 数値配列

GPU ベースの System object は、gpuArray クラスを使用して作成された一般的な MATLAB 配列またはオブジェクトを受け入れます。GPU ベースの System object は、倍精度または単精度データ型の入力信号をサポートします。出力信号のデータ型は、入力信号から継承されます。

  • 入力信号が MATLAB 配列の場合、System object は CPU と GPU の間のデータ転送を処理します。出力信号は MATLAB 配列です。

  • 入力信号が gpuArray の場合、データは GPU に残ります。出力信号は gpuArray です。オブジェクトに gpuArray が渡されると、計算がすべて GPU 上で実行され、データ転送は発生しません。gpuArray 引数を渡すことにより、シミュレーション時間が短縮されてパフォーマンスが向上します。詳細は、GPU での配列の確立 (Parallel Computing Toolbox)を参照してください。

GPU System object に MATLAB 配列を渡すには、CPU から GPU に初期データを転送しなければなりません。その後、GPU System object により計算が実行され、出力データが CPU に返されます。このプロセスでレイテンシが発生します。gpuArray の形式でデータを GPU System object に渡す場合、オブジェクトはデータ転送によるレイテンシを課されません。このため、入力として gpuArray を提供すると、GPU System object の実行速度は向上します。

一般的に、シミュレーションでは CPU と GPU 間のデータ転送は最小限に抑えるようにします。

gpuArray を入力として渡す

この例では、PSK 変調器の入力に gpuArray を渡してレイテンシを低減させる方法を示します。

pskGPUModulator = comm.gpu.PSKModulator;
x = randi([0 7], 1000, 1, 'single');
gx = gpuArray(x);
 
o = pskGPUModulator(x);
class(o)
 
release(pskGPUModulator); %allow input types to change
 
go = pskGPUModulator(gx);
class(go)

System ブロックでの GPU System object のサポート

System ブロックでサポートされている 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

System ブロックでの GPU System object に関する制限

GPU System object は [インタープリター型実行] を使用してシミュレーションしなければなりません。このオプションはブロック マスクで明示的に選択しなければなりません。既定値は [コード生成] です。

関連するトピック