这个例子展示了在MATLAB®中加速通信算法仿真的两种方法。它展示了使用MATLAB对C代码生成和并行处理运行时的性能影响(使用MATLAB)帕弗
(并行计算工具箱)功能)。要全面了解所有可能的加速技术,请参见加速MATLAB算法及应用篇文章。
使用这些方法的综合效果可能会将典型的模拟时间缩短一个数量级。这种差异相当于在一夜之间或几小时内运行模拟。
要运行本例中的MATLAB到C代码生成部分,您必须拥有MATLAB Coder™产品。要运行本示例的并行处理部分,您必须拥有并行计算工具箱™产品。
这个例子检验了这个收发信机系统在MATLAB中的各种实现。
该系统由发射机、信道模型和接收机组成。发射机用卷积编码器、交织器、调制器和MIMO空时块编码器处理输入比特流(见[1.], [2.])。传输信号通过2x2 MIMO块衰落信道和加性高斯白噪声(AWGN)信道处理。接收机用2x2 MIMO空时块解码器、解调器、解交错器和维特比解码器处理其输入信号,以恢复接收机输入比特流的最佳估计。
该示例遵循以下工作流:
创建一个运行模拟算法的函数
使用MATLAB Profiler GUI识别速度瓶颈
用MATLAB加速仿真到C代码的生成
使用并行处理运行实现更快的模拟
从表示此算法的第一个版本或基线实现的函数开始helperAccelBaseline
功能是
当前帧的值(EbNo
),最小错误数(minNumErr
)以及处理的最大位数(maxNumBits
).
是每比特能量与噪声功率谱密度之比。函数输出是每比特的误码率(BER)信息
点。
类型helperAccelBaseline
函数数量= helperAccelBaseline (EbNo、minNumErr maxNumBits) = % helperAccelBaseline模拟通信链路%误码率helperAccelBaseline (EbNo, MINERR MAXBIT)返回的位错误%率(ber)通信链路,其中包括卷积编码、%交错,QAM调制,Alamouti时空分组码,和带AWGN的% MIMO块衰落信道。EBNO是%的每一点能量噪声功率谱密度比(Eb /不)AWGN信道在dB, % MINERR收集的最低数量是错误,和MAXBIT %最大数量的模拟部分,以便模拟不会无限期地%如果Eb /不值太高了。版权所有The MathWorks, Inc.M = 16;%调制阶k = log2(M);每符号编码%位= 1/2;%编码率adjSNR = EbNo - 10*log10(1/codeRate) + 10*log10(k);Trellis = 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循环的处理
值从0到7 dB。
minEbNodB=0;maxEbNodB=7;EbNoVec=minEbNodB:maxEbNodB;minNumErr=100;maxNumBits=1e6;N=1;str=“基线”;%运行该函数一次,将其加载到内存中,并从%运行时测量HelperAccelbBaseline(3,10,1e4);berBaseline=0(大小(minEbNodB:maxebNodeb));disp(“处理基线算法。”);
处理基线算法。
抽搐;为EbNoIdx=1:length(EbNoVec);y = helperAccelBaseline (EbNo minNumErr maxNumBits);berBaseline (EbNoIdx) = y (1);结束rtBaseline=toc;
结果显示了基线算法的仿真时间(以秒为单位)。使用此计时度量与后续加速模拟运行时进行比较。
helperAccelReportResults (N, rtBaseline rtBaseline str, str);
----------------------------------------------------------------------------------------------收发器版本|运行时间(秒)|加速比1.基线| 4.4886 | 1.0000----------------------------------------------------------------------------------------------
利用MATLAB Profiler确定基线算法的处理瓶颈和问题区域。执行以下脚本获取分析器信息:
轮廓在y = helperAccelBaseline(6100年,1 e6);轮廓从轮廓查看器
这个性能分析报告给出算法的每个函数调用的执行时间。您可以按照自生时间降序对函数进行排序。Profiler窗口所描述的前几个函数代表了算法的速度瓶颈。在这种情况下vitdec
功能被确定为主要的速度瓶颈。
MATLAB编码器生成可移植和可读的C代码,从算法,是MATLAB代码生成子集的一部分。的MATLAB可执行文件(MEX)helperAccelBaseline
,因为它使用支持代码生成的函数和System对象。金宝app使用编码基因
(MATLAB编码器)函数编译helperAccelBaseline
函数转换为MEX函数。在codegen成功生成代码之后,您将在工作区中看到一个MEX文件,该文件将'_mex'附加到函数中,helperAccelBaseline_mex
.
编码基因(“helperAccelBaseline.m”,“参数”,{EbNo,minNumErr,maxmnumbits})
代码生成成功。
测量算法MEX版本的仿真时间。记录在同一个for循环中运行此函数所需的时间。
N = N + 1;str =MATLAB到C的代码生成;标签=“Codegen”;1 e4 helperAccelBaseline_mex(10日);berCodegen = 0(大小(berBaseline));disp ('处理算法的MEX函数');
处理算法的MEX函数。
抽搐;为EbNoIdx=1:length(EbNoVec);y = helperAccelBaseline_mex (EbNo minNumErr maxNumBits);berCodegen (EbNoIdx) = y (1);结束rt = toc;
这里的结果表明,该算法的MEX版本比该算法的基线版本运行得更快。实现的加速量取决于该算法的性质。确定加速的最佳方法是使用MATLAB编码器生成MEX函数,并直接测试加速比。如果您的算法包含单个precision数据类型、定点数据类型、具有状态的循环或无法矢量化的代码,您可能会看到加速。另一方面,如果您的算法包含MATLAB隐式多线程计算,例如fft
和svd
,调用IPP或BLAS库的函数,为在PC(如FFTs)上的MATLAB中执行而优化的函数,或可对代码进行矢量化的算法,加速的可能性较小。
helperAccelReportResults(N、rtBaseline、rt、str、tag);
----------------------------------------------------------------------------------------------收发器版本|运行时间(秒)|加速比1。基线| 4.4886 | 1.0000 2。MATLAB到C代码生成| 1.6402 | 2.7367----------------------------------------------------------------------------------------------
利用多个核,通过并行运行任务来增加模拟加速。使用并行处理运行(帕弗
循环)以对可用工作人员的数量执行工作。并行计算工具箱使您能够并行运行模拟的不同迭代。使用gcp
(并行计算工具箱)函数获取当前并行池。如果池可用但未开放,则gcp
打开池并保留几个MATLAB工作者来执行后续的迭代帕弗
循环。在本例中,六个工作人员在MATLAB客户机上本地运行。
池=gcp
NumWorkers: 6 Cluster: local attachdfiles: {} AutoAddClientPath: true IdleTimeout: 30 minutes (5 minutes remaining) SpmdEnabled: true . pool = processspool with properties: Connected: true NumWorkers: 6 Cluster: local attachdfiles: {} AutoAddClientPath: true IdleTimeout: 30 minutes (5 minutes remaining
跑
点平行使用六个工人使用帕弗
-循环,而不是前面案例中使用的for循环。测量模拟时间。
N = N + 1;str ='Parallel runs with parfor over Eb/No';标签=“Parfor Eb /不”; HelperAccelbBaseline_-mex(3,10,1e4);berParfor1=零(大小(BERB基线));disp(在parfor循环中处理算法的MEX函数);
在parfor循环中处理算法的MEX函数。
抽搐;帕弗EbNoIdx=1:length(EbNoVec);y = helperAccelBaseline_mex (EbNo minNumErr maxNumBits);berParfor1 (EbNoIdx) = y (1);结束rt = toc;
结果添加了在一个时间段内执行的MEX版本算法的模拟时间帕弗
-循环到前面的结果。请注意,通过在帕弗
-循环时,完成模拟的时间更短。a的基本概念帕弗
-loop与标准MATLAB for loop相同,不同之处在于帕弗
将循环迭代划分为组,以便每个工作人员执行总迭代数的一部分。由于几个MATLAB工作人员可以在同一个循环上并发计算,因此,a帕弗
-loop提供了比普通串行for循环更好的性能。
helperAccelReportResults(N、rtBaseline、rt、str、tag);
---------------------------------------------------------------------------------------------- 版本的收发机|运行时间(sec) |加速度比1。基线| 4.4886 | 1.0000 2。MATLAB到C的代码生成| 1.6402 | 2.7367 3。并行运行与parfor Eb /不| 1.0943 | 4.1020 ----------------------------------------------------------------------------------------------
在前一节中,总的模拟时间主要由最高决定
点。您可以进一步加速模拟,方法是将每个模拟的位数相乘
指向工人们,每个人都跑
点并行使用六位工人使用帕弗
循环。测量模拟时间。
N = N + 1;str =' parfor并行运行超过位数';标签=“Parfor#Bits”;HelperAccelbBaseline_-mex(3,10,1e4);berParfor2=零(大小(berBaseline));显示(“在parfor循环中处理第二版算法的MEX函数。”);
在parfor循环中处理算法第二版本的MEX函数。
抽搐;%计算每个worker上要模拟的位数minNumErrPerWorker = minNumErr / pool.NumWorkers;maxNumBitsPerWorker = maxNumBits / pool.NumWorkers;为EbNoIdx=1:length(EbNoVec);numErr = 0 (pool.NumWorkers, 1);帕弗w = 1:池。NumWorkers y=helperAccelBaseline_mex(EbNo,minNumErrPerWorker,maxNumBitsPerWorker); numErr(w)=y(2); numBits(w)=y(3);结束berParfor2(EbNoIdx)=总和(numer)/总和(numBits);结束rt = toc;
结果添加了在一个时间段内执行的MEX版本算法的模拟时间帕弗
-loop,此时每个worker模拟相同
点。请注意,通过在帕弗
-loop我们得到最快的模拟性能。区别在于帕弗
除以工人需要模拟的比特数。这种方法减少了甚至最高的模拟时间
通过将负载(特别是要模拟的比特数)均匀分布在工人身上来计算。
helperAccelReportResults(N、rtBaseline、rt、str、tag);
---------------------------------------------------------------------------------------------- 版本的收发机|运行时间(sec) |加速度比1。基线| 4.4886 | 1.0000 2。MATLAB到C的代码生成| 1.6402 | 2.7367 3。与parfor并行运行的Eb/No | 1.0943 | 4.1020 4。并行运行与parfor | 0.6501 | 6.9043的比特数 ----------------------------------------------------------------------------------------------
通过结合MATLAB到C代码生成和并行处理运行的效果,可以显著加快通信算法的模拟。
MATLAB to C代码生成通过锁定每个变量的数据类型和大小,并通过减少在代码的每一行中检查变量大小和数据类型的解释语言的开销来加速模拟。
并行处理运行可以通过在多个MATLAB工作者中并行地计算算法的不同迭代来大大加速模拟。
并行每个 单点可以进一步加速,甚至可以加速最长的跑步 点。
下面的条形图显示了所有四种方法的运行时。结果可能会根据具体的算法、可用的工作者以及最小错误数和最大比特数的选择而有所不同。
结果=helperAccelReportResults;
该图显示了不同模拟处理方法的误码率曲线彼此非常匹配
该算法的四个版本中,每个版本的最大输入位数设置为1000万(maxNumBits
=1e7)且最小位错误数设置为5000(minNumErr
= 5000)。
本示例使用gcp
函数用于保留在MATLAB客户机机器上本地运行的几个MATLAB工作程序。通过修改并行配置,您可以在不在您的MATLAB客户机上的更大的工作集群上运行算法,从而进一步加速模拟。有关如何管理和使用并行配置的描述,请参阅发现集群并使用集群配置文件(并行计算工具箱)的话题。
本例中使用了以下函数。
S. M. Alamouti,《无线通信的简单传输分集技术》,IEEE®通信选定领域期刊,第16卷,第5期。8、1998年10月第1451-1458页。
V. Tarokh, H. Jafarkhami, A. R. Calderbank,《来自正交设计的时空块代码》,IEEE信息论学报,第45卷,第5期,第1456-1467页,1999年7月。