主要内容

仿真加速使用MATLAB编码器和并行计算工具箱

本例展示了在MATLAB®中加速通信算法仿真的两种方法。它展示了使用MATLAB对C代码生成和并行处理运行的运行时性能影响(使用MATLABparfor(并行计算工具箱)功能)。要全面了解所有可能的加速技术,请参见加速MATLAB算法及应用篇文章。

使用这些方法的综合效果可以使典型的模拟时间加快一个数量级。这种差异相当于在一夜之间或短短几个小时内运行模拟。

要运行此示例的MATLAB到C代码生成部分,您必须拥有MATLAB Coder™产品。要运行此示例的并行处理部分,必须使用并行计算工具箱™产品。

示例结构

本例研究了该收发器系统在MATLAB中的各种实现。

该系统由发射机、信道模型和接收机组成。发射器使用卷积编码器、交织器、调制器和MIMO时空块编码器处理输入比特流(参见[1]、[2])。传输信号经过2 × 2 MIMO块衰落信道和加性高斯白噪声信道处理。接收机使用一个2x2 MIMO空时块解码器、一个解调器、一个去交织器和一个维特比解码器处理输入信号,以恢复接收机处输入比特流的最佳估计。

示例如下:

  1. 创建一个运行模拟算法的函数

  2. 使用MATLAB Profiler GUI识别速度瓶颈

  3. 加速仿真用MATLAB到C代码的生成

  4. 使用并行处理运行实现更快的模拟

创建运行模拟算法的函数

从表示该算法的第一个版本或基线实现的函数开始。的输入helperAccelBaseline函数是 E b / N o 当前帧(EbNo),最小错误数(minNumErr)和处理的最大比特数(maxNumBits). E b / N o 是每比特能量与噪声功率谱密度的比值。函数输出是每个函数的误码率(BER)信息 E b / N o 点。

类型helperAccelBaseline
function ber = helperAccelBaseline(EbNo, minNumErr, maxNumBits) %helperAccelBaseline模拟通信链路% ber = helperAccelBaseline(EbNo, MINERR,MAXBIT)返回通信链路的误码率(ber),该通信链路包括卷积编码,%交织,QAM调制,Alamouti空时块码和% MIMO块衰减信道。EBNO是AWGN信道的每比特能量与%噪声功率谱密度之比(Eb/No),单位为dB, % miner是要收集的最小错误数,MAXBIT是最大模拟比特数%,这样当Eb/No值过高时,模拟不会无限期地运行%。版权所有:The MathWorks, Inc.M = 16;%调制阶k = log2(M);%比特每符号codeRate = 1/2;%编码率adjSNR = convertSNR(EbNo," EbNo ","BitsPerSymbol",k,"CodingRate",codeRate);格子= poly2trellis(7,[171 133]);Tblen = 32;dataFrameLen = 1998; % Add 6 zeros to terminate the convolutional code chanFrameLen=(dataFrameLen+6)/codeRate; permvec=[1:3:chanFrameLen 2:3:chanFrameLen 3:3:chanFrameLen]'; ostbcEnc = comm.OSTBCEncoder(NumTransmitAntennas=2); ostbcComb = comm.OSTBCCombiner(NumTransmitAntennas=2,NumReceiveAntennas=2); mimoChan = comm.MIMOChannel(MaximumDopplerShift=0,PathGainsOutputPort=true); berCalc = comm.ErrorRate; % Run Simulation ber = zeros(3,1); while (ber(3) <= maxNumBits) && (ber(2) < minNumErr) data = [randi([0 1],dataFrameLen,1);false(6,1)]; encOut = convenc(data,trellis); % Convolutional Encoder intOut = intrlv(double(encOut),permvec'); % Interleaver modOut = qammod(intOut,M,... 'InputType','bit'); % QAM Modulator stbcOut = ostbcEnc(modOut); % Alamouti Space-Time Block Encoder [chanOut, pathGains] = mimoChan(stbcOut); % 2x2 MIMO Channel chEst = squeeze(sum(pathGains,2)); rcvd = awgn(chanOut,adjSNR,'measured'); % AWGN channel stbcDec = ostbcComb(rcvd,chEst); % Alamouti Space-Time Block Decoder demodOut = qamdemod(stbcDec,M,... 'OutputType','bit'); % QAM Demodulator deintOut = deintrlv(demodOut,permvec'); % Deinterleaver decOut = vitdec(deintOut(:),trellis, ... % Viterbi Decoder tblen,'term','hard'); ber = berCalc(decOut(1:dataFrameLen),data(1:dataFrameLen)); end

作为起点,测量在MATLAB中运行此基线算法所需的时间。使用MATLAB定时函数(抽搐而且toc)来记录经过的运行时,以完成for循环的遍历处理 E b / N o 值从0到7 dB。

minEbNodB = 0;maxEbNodB = 7;EbNoVec = minEbNodB:maxEbNodB;minNumErr = 100;maxNumBits = 1 e6;N = 1;str =“基线”运行该函数一次,将其加载到内存中,并从内存中删除开销%运行时测量1 e4 helperAccelBaseline(10日);berBaseline = 0(大小(minEbNodB: maxEbNodB));disp ('处理基线算法。');
处理基线算法。
抽搐;EbNoIdx=1:length(EbNoVec) EbNo = EbNoVec(EbNoIdx);y = helperAccelBaseline (EbNo minNumErr maxNumBits);berBaseline (EbNoIdx) = y (1);结束rtBaseline = toc;

结果显示了基线算法的仿真时间(单位为秒)。使用此计时测量与后续加速模拟运行时进行比较。

helperAccelReportResults (N, rtBaseline rtBaseline str, str);
---------------------------------------------------------------------------------------------- 版本的收发机|运行时间(sec) |加速度比1。基线| 5.5712 | 1.0000  ----------------------------------------------------------------------------------------------

通过使用MATLAB Profiler App识别速度瓶颈

使用MATLAB Profiler识别基线算法的处理瓶颈和问题领域。通过执行以下脚本获取分析器信息:

配置文件y = helperAccelBaseline(6100年,1 e6);配置文件配置文件查看器

性能分析报告显示算法的每个函数调用的执行时间。您可以根据函数的自时间降序对它们进行排序。Profiler窗口描述的前几个函数表示算法的速度瓶颈。在这种情况下,vitdec功能被认为是主要的速度瓶颈。

用MATLAB加速仿真生成C代码

MATLAB Coder从属于MATLAB代码生成子集的算法生成可移植和可读的C代码。可以创建一个MATLAB可执行文件(MEX)的helperAccelBaseline,因为它使用了支持代码生成的函数和系统对象。金宝app使用codegen(MATLAB编码器)函数编译helperAccelBaseline函数转换为MEX函数。在codegen成功生成代码后,您将在工作区中看到一个MEX文件,该文件将'_mex'附加到函数中,helperAccelBaseline_mex

codegen (“helperAccelBaseline.m”“参数”, {EbNo、minNumErr maxNumBits})
代码生成成功。

测量MEX版本算法的仿真时间。记录在相同的for循环中运行此函数所花费的时间。

N = N + 1;str =MATLAB到C代码生成;标签=“Codegen”;1 e4 helperAccelBaseline_mex(10日);berCodegen = 0(大小(berBaseline));disp (处理算法的MEX函数);
处理算法的MEX函数。
抽搐;EbNoIdx=1:length(EbNoVec) EbNo = EbNoVec(EbNoIdx);y = helperAccelBaseline_mex (EbNo minNumErr maxNumBits);berCodegen (EbNoIdx) = y (1);结束rt = toc;

这里的结果表明,该算法的MEX版本比算法的基线版本运行得更快。实现的加速量取决于算法的性质。确定加速度的最佳方法是使用MATLAB Coder生成一个mex函数并直接测试加速。如果您的算法包含单精度数据类型、定点数据类型、带状态的循环或不能向量化的代码,则可能会看到加速。另一方面,如果您的算法包含MATLAB的隐式多线程计算,如fft而且圣言会例如,调用IPP或BLAS库的函数,为在PC上的MATLAB中执行而优化的函数(如fft),或者可以向量化代码的算法,这些都不太可能加速。

helperAccelReportResults (N, rtBaseline, rt、str标记);
---------------------------------------------------------------------------------------------- 版本的收发机|运行时间(sec) |加速度比1。基线| 5.5712 | 1.0000MATLAB与C代码生成| 1.6952 | 3.2864  ----------------------------------------------------------------------------------------------

使用并行处理运行实现更快的模拟

利用多核通过并行运行任务来增加模拟加速。使用并行处理运行(parfor循环)在MATLAB中执行的工作上可用的工人的数量。“并行计算工具箱”使您能够并行地运行模拟的不同迭代。使用gcp(并行计算工具箱)函数获取当前并行池。如果池可用但未打开,则gcp打开池并保留几个MATLAB工作者来执行后续的迭代parfor循环。在本例中,有6个worker在MATLAB客户机上本地运行。

Pool = GCP
使用“本地”配置文件启动并行池(parpool)…连接到并行池(number of workers: 6). pool = ProcessPool with properties: Connected: true NumWorkers: 6 Busy: false Cluster: local AttachedFiles: {} AutoAddClientPath: true IdleTimeout: 30 minutes(剩余30分钟)SpmdEnabled: true

并行运行Eb/No值

运行 E b / N o 点平行使用六个工人使用一个parfor-loop而不是前面使用的for循环。测量模拟时间。

N = N + 1;str =“平行运行与parfor在Eb/No”;标签=“Parfor Eb /不”;1 e4 helperAccelBaseline_mex(10日);berParfor1 = 0(大小(berBaseline));disp (在parfor循环中处理算法的MEX函数);
在parfor-loop中处理算法的MEX函数。
抽搐;parforEbNoIdx=1:length(EbNoVec) EbNo = EbNoVec(EbNoIdx);y = helperAccelBaseline_mex (EbNo minNumErr maxNumBits);berParfor1 (EbNoIdx) = y (1);结束rt = toc;

结果添加了算法的MEX版本的仿真时间parfor-循环到之前的结果。注意,通过在parfor-loop,完成模拟所需的时间更短。a的基本概念parfor-loop与标准的MATLAB for-loop相同。区别在于parfor将循环迭代划分为组,以便每个工作人员执行迭代总数的一部分。因为几个MATLAB工作者可以在同一个循环上并发地计算,aparfor-loop提供了比普通串行for循环更好的性能。

helperAccelReportResults (N, rtBaseline, rt、str标记);
---------------------------------------------------------------------------------------------- 版本的收发机|运行时间(sec) |加速度比1。基线| 5.5712 | 1.0000用MATLAB编写的C代码生成| 1.6952 | 3.2864 3.。并行运行与parfor Eb /不| 1.4367 | 3.8779  ----------------------------------------------------------------------------------------------

并行运行比特数

在上一节中,总的模拟时间主要由最高来决定 E b / N o 点。您可以通过划分每个模拟的比特数来进一步加速模拟 E b / N o 指向工人们。运行每个 E b / N o 点平行使用六个工人使用一个parfor循环。测量模拟时间。

N = N + 1;str =并行运行parfor超过比特数;标签=Parfor # Bits;1 e4 helperAccelBaseline_mex(10日);berParfor2 = 0(大小(berBaseline));disp (在parfor-loop中处理算法的第二个版本的MEX函数);
在parfor-loop中处理算法的第二个版本的MEX函数。
抽搐;计算要在每个worker上模拟的比特数minNumErrPerWorker = minNumErr / pool.NumWorkers;maxNumBitsPerWorker = maxNumBits / pool.NumWorkers;EbNoIdx=1:length(EbNoVec) EbNo = EbNoVec(EbNoIdx);number r = 0 (pool.NumWorkers,1);parforw = 1:池。NumWorkers y=helperAccelBaseline_mex(EbNo,minNumErrPerWorker,maxNumBitsPerWorker); numErr(w)=y(2); numBits(w)=y(3);结束berParfor2 (EbNoIdx) = (numErr) /金额总和(numBits);结束rt = toc;

结果添加了算法的MEX版本的仿真时间parfor-loop,这一次每个worker模拟相同的 E b / N o 点。注意,通过在parfor我们得到了最快的模拟性能。区别在于parfor将需要模拟的比特数除以worker。这种方法减少了仿真时间,即使是最高的 E b / N o 通过在工人上均匀分配负载(具体来说,要模拟的比特数)来计算值。

helperAccelReportResults (N, rtBaseline, rt、str标记);
---------------------------------------------------------------------------------------------- 版本的收发机|运行时间(sec) |加速度比1。基线| 5.5712 | 1.0000用MATLAB编写的C代码生成| 1.6952 | 3.2864 3.。b/No | 1.4367 | 3.8779 4。并行运行与parfor | 0.9522 | 5.8507的比特数  ----------------------------------------------------------------------------------------------

总结

通过MATLAB到C代码生成和并行处理运行的组合效果,您可以显著加快通信算法的模拟速度。

  • MATLAB到C的代码生成通过锁定每个变量的数据类型和大小,以及通过减少解释语言的开销来加速模拟,解释语言在代码的每一行中检查变量的大小和数据类型。

  • 并行处理运行可以通过在多个MATLAB工作线程上并行计算算法的不同迭代来大大加速仿真。

  • 并行每个 E b / N o 点单独可以加速进一步加速,即使是最长的运行 E b / N o 点。

下面以柱状图的形式显示了所有四种方法的运行时间。结果可能会根据特定的算法、可用的worker以及对最小错误数和最大比特数的选择而有所不同。

results = helperAccelReportResults;

该图显示了不同仿真处理方法的误码率曲线彼此紧密匹配。对于每一个绘图 E b / N 0 该算法的四个版本中,每个版本的最大输入位数都设置为1000万(maxNumBits=1e7),最小误码数设置为5000 (minNumErr= 5000)。

进一步的探索

本例使用gcp函数保留几个在MATLAB客户端机器上本地运行的MATLAB工作者。通过修改并行配置,可以在不在MATLAB客户端机器上的更大的工作集群上运行算法,从而进一步加速模拟。有关如何管理和使用并行配置的说明,请参见发现集群并使用集群概要文件(并行计算工具箱)的话题。

本例中使用了以下函数。

选择引用

  1. S. M. Alamouti,“一种简单的无线通信传输分集技术”IEEE通信选定领域期刊,第16卷,no。8,页1451-1458,1998年10月。

  2. V. Tarokh, H. Jafarkhami和A. R. Calderbank,“正交设计中的时空分组码”,IEEE信息论汇刊,第45卷,no。5,第1456-1467页,1999年7月。