Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

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

MATLAB System block mask with the Interpreted execution option selected

関連するトピック