主要内容

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

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

使用这些方法的综合效果可以使典型的模拟时间加快一个数量级。不同之处在于运行整夜的模拟或仅仅在几个小时内。

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

示例结构

这个例子检验了该收发器系统在MATLAB中的各种实现。

block_diagram.PNG

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

该示例遵循以下工作流程:

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

  2. 使用MATLAB分析器GUI识别速度瓶颈

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

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

创建运行模拟算法的函数

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

类型helperAccelBaseline
函数ber = helperAccelBaseline(EbNo, minNumErr, maxNumBits) % ber = helperAccelBaseline(EbNo, MINERR,MAXBIT)返回通信链路的误码率(ber),该通信链路包括卷积编码、%交错、QAM调制、Alamouti空时块码和含有AWGN的% MIMO块衰落信道。EBNO是dB中AWGN信道的每比特能量与%噪声功率谱密度之比(Eb/No), % MINERR是要收集的最小错误数,而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。基线| 6.6191 | 1.0000  ----------------------------------------------------------------------------------------------

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

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

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

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

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

MATLAB Coder从属于MATLAB代码生成子集的算法中生成可移植和可读的C代码。您可以创建一个MATLAB可执行文件(MEX)helperAccelBaseline函数,因为它使用支持代码生成的函数和System对象。使用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编码器生成一个mex函数,并直接测试加速。如果您的算法包含单精度数据类型、定点数据类型、带状态的循环或无法向量化的代码,那么您可能会看到加速。另一方面,如果您的算法包含MATLAB隐式多线程计算,如fft而且圣言会例如,调用IPP或BLAS库的函数、为在PC上的MATLAB中执行而优化的函数(如FFTs),或者可以对代码进行向量化的算法,加速的可能性较小。

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

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

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

池= gcp
pool = 0×0没有属性的池数组。
如果Isempty (pool) pool = parpool结束
使用“本地”配置文件启动并行池(parpool)…连接到并行池(worker的数量:6). pool = ProcessPool with properties: Connected: true NumWorkers: 6 Busy: false Cluster: local AttachedFiles: {} AutoAddClientPath: true FileStore: [1x1 parallel.]FileStore] ValueStore: [1x1 parallel.]ValueStore] IdleTimeout: 30 minutes (30 minutes remaining) SpmdEnabled: true

并行运行Eb/No值

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

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

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

helperAccelReportResults (N, rtBaseline, rt、str标记);
---------------------------------------------------------------------------------------------- 版本的收发机|运行时间(sec) |加速度比1。基线| 6.6191 | 1.000用MATLAB到C代码生成| 1.4821 | 4.4661 3。并行运行与parfor Eb /不| 1.2459 | 5.3127  ----------------------------------------------------------------------------------------------

并行运行比特数

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

N = N + 1;str =“parfor /比特数的并行运行”;标签=“Parfor #位”;1 e4 helperAccelBaseline_mex(10日);berParfor2 = 0(大小(berBaseline));disp (在parfor循环中处理算法的第二个版本的MEX函数);
在parfor循环中处理算法的第二个版本的MEX函数。
抽搐;计算每个工作机上要模拟的比特数minNumErrPerWorker = minNumErr / pool.NumWorkers;maxNumBitsPerWorker = maxNumBits / pool.NumWorkers;EbNoIdx=1:length(EbNoVec) EbNo = EbNoVec(EbNoIdx);numErr = 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-循环,这一次每个worker模拟相同的 E b / N o 点。注意,通过在parfor-循环我们得到最快的模拟性能。区别在于parfor用需要模拟的比特数除以工作者数。这种方法甚至减少了最高的模拟时间 E b / N o 通过在工作人员上均匀分配负载(具体地说,要模拟的比特数)来赋值。

helperAccelReportResults (N, rtBaseline, rt、str标记);
---------------------------------------------------------------------------------------------- 版本的收发机|运行时间(sec) |加速度比1。基线| 6.6191 | 1.000用MATLAB到C代码生成| 1.4821 | 4.4661 3。b/No | 1.2459 | 5.3127并行运行与parfor | 0.8802 | 7.5201的比特数  ----------------------------------------------------------------------------------------------

总结

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

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

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

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

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

结果= helperAccelReportResults;

图中包含一个axes对象。axes对象包含一个bar类型的对象。

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

ber_results.PNG

进一步的探索

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

本例中使用了以下函数。

选择引用

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

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

Baidu
map