折叠S-Functions支持表达金宝app式
使用表达式折叠增加效率自己内联函数所生成的代码块,通过调用宏功能提供的API。
s函数API允许您指定一个给定的功能块是否应该名义上接受表达式在给定的输入端口。一块不应该总是接受表达式。例如,如果使用地址信号的输入,输入表达式不应该接受,因为它是不可能的一个表达式的地址。
s函数API还允许您指定一个表达式是否能代表与一个给定的输出端口相关的计算。当你要求一个表达式在一块的输入或输出端口,仿真软件金宝app®引擎决定了是否可以请求的荣誉,鉴于块的上下文。例如,发动机可能否认一个街区的要求输出表达式,如果目的地块不接受在其输入表达式,如果目的地块有一个更新函数,或如果存在多个输出目的地。
决定荣誉或拒绝一个请求的输出表达式也可以依靠输出表达式块使用的类别。
利用表达S-functions折叠,你应该明白什么时候请求接受为特定的块和一代的表情。你不需要理解的算法仿真软件引擎选择接受或拒绝这些请求。金宝app然而,如果你想跟踪模型和生成的代码,它有助于理解的一些比较常见的情况,导致拒绝请求。
类别的输出表达式
当你实现一个C墨西哥人s函数,您可以指定是否对应的代码块的输出是生成一个表达式。如果块生成一个表达式,您必须指定表达式常数,微不足道的,或通用的。
一个常数输出表达式直接访问块的一个参数。例如,恒定的输出块被定义为一个常数表达式,因为输出表达式只是一块直接访问的价值
参数。
一个微不足道的输出表达式是一个表达式,可以重复,没有性能损失,当输出端口有多个输出目的地。例如,的输出单位延迟块定义为一个简单的表达式,因为输出表达式只是一块直接访问的状态。因为输出表达式没有计算,它可以重复多次没有降解生成的代码的性能。
一个通用的输出表达式是一个表达式,应该认为有性能损失如果重复。这样,一个通用的输出表达式时不适合重复输出端口有多个输出目的地。例如,和块的输出是一个通用的,而不是一个简单的表达式,因为它是昂贵的验算和块输出表达式作为输入多个块。
琐碎的和通用的输出表达式的例子
考虑这个框图。延迟块有多个目的地,然而它的输出被指定为一个简单的输出表达式,以便它可以使用不止一次没有降低代码的效率。
这个代码片段显示了生成的代码单位延迟块在这个框图。三根输出直接分配的状态单位延迟块,这是存储在一个全局数据结构的字段rtDWork
。因为作业是直接,没有表情,没有性能损失与使用多个目的地的简单表达式。
空白MdlOutputs (int_T tid) {…/ *输出港:< Root > /着干活了:* UnitDelay: < Root > /单位* /而延迟。着干活= rtDWork.Unit_Delay_DSTATE;/ *输出港:< Root > / Out2包含:* UnitDelay: < Root > /单位* /而延迟。Out2 = rtDWork.Unit_Delay_DSTATE;/ *输出港:< Root > / Out3包含:* UnitDelay: < Root > /单位* /而延迟。Out3 = rtDWork.Unit_Delay_DSTATE;…}
生成的代码显示了如何生成代码和街区与单个和多个目的地。
另一方面,考虑和块在这个模型:
上和块模型中生成标记信号non_triv
。计算这个输出信号包括两个乘法和加法。如果允许和块的输出来生成一个表达式即使块有多个目的地,块的操作会在生成的代码重复。在这种情况下,生成的表达式将扩散四个乘法和两个补充。这将降低程序的效率。相应的输出和块不允许一个表达式,因为它有多个目的地。
仿真软件金宝app引擎不允许上和块的输出是一个表达式,因为这个信号non_triv
被路由到两个输出目的地。相反,乘法和加法操作的结果存储在一个临时变量(rtb_non_triv)
两次引用的语句,如下代码摘录中看到的一样。
相比之下,低和块,只有一个输出目的地(Out2
),并生成一个表达式。
空白MdlOutputs (int_T tid){/ *本地块i / o变量* / real_T rtb_non_triv;real_T rtb_Sine_Wave;/ *金额:< Root > /金额包含:*获得:< Root > /获得*尺寸:< Root > / u1 *获得:< Root > / Gain1 *尺寸:< Root > / u2关于< Root > /增益:* * *获得价值:rtP。关于< Root > / Gain1 Gain_Gain * *: *增益值:rtP。Gain1_Gain * / rtb_non_triv = (rtP。Gain_Gain * rtU.u1) + (rtP。Gain1_Gain * rtU.u2);/ *输出港:< Root > /着干活* /而无。着干活= rtb_non_triv;/ *罪:< Root > /正弦波* / rtb_Sine_Wave = rtP。Sine_Wave_Amp * sin (rtP。Sine_Wave_Freq * rtmGetT (rtM_model) + rtP.Sine_Wave_Phase) + rtP.Sine_Wave_Bias;/ *输出港:< Root > / Out2包含:*金额:< Root > / Sum1 * /而无。Out2 = (rtb_non_triv + rtb_Sine_Wave);}
指定输出表达式的类别
功能的API提供了宏,让您声明一个块的输出是否应该一个表达式,如果是这样的话,指定表达式的类别。这个表指定当宣布块输出是一个常数,琐碎,或通用的输出表达式。
类型的输出表达式
类别的表达式 |
什么时候使用 |
---|---|
常数 |
使用只有块输出是一块直接内存访问参数。 |
微不足道的 |
使用只有块输出是一个表达式,可以出现多次在代码中没有减少效率(例如,一个直接内存访问的字段 |
通用的 |
如果输出是一个表达式,但不是常数或微不足道的。 |
你必须声明输出的表达式mdlSetWorkWidths
使用宏定义在函数API函数。宏有以下参数:
SimStruct *年代
:块的指针SimStruct
。int idx:
输出端口的从零开始的索引。bool值:
通过真实如果端口生成输出表达式。
下面的宏可以设置一个输出是一个常数,琐碎,或通用表达式:
空白ssSetOutputPortConstOutputExprInRTW (int idx SimStruct *年代,bool值)
空白ssSetOutputPortTrivialOutputExprInRTW (int idx SimStruct *年代,bool值)
空白ssSetOutputPortOutputExprInRTW (int idx SimStruct *年代,bool值)
以下宏用于查询之前设定的状态调用宏上图:
bool ssGetOutputPortConstOutputExprInRTW (SimStruct * S, int idx)
bool ssGetOutputPortTrivialOutputExprInRTW (SimStruct * S, int idx)
bool ssGetOutputPortOutputExprInRTW (SimStruct * S, int idx)
的通用表达式是一个简单的集合表达式的超集,和简单的集合表达式是集的超集常数表达式。
因此,当你查询一组输出一直是一个常数表达式ssGetOutputPortTrivialOutputExprInRTW
,它返回真正的
。一个常数表达式被认为是一个简单的表达式,因为它是一个直接存储器存取,可以重复没有降解生成的代码的效率。
同样,一个输出,被配置为一个常数或简单的表达式返回真正的
当查询地位一般表达式。
接受或拒绝请求输入表达式
一块要求其输出可以在代码中表示为一个表达式。这样的请求会被拒绝,如果目的地块不能接受表达式的输入端口。此外,条件独立的请求块和目的地块可以防止接受表达式。
一块不应在其输入端口配置为接受表达式在下列条件:
块必须把其输入数据的地址。它是不可能大多数类型的输入的地址表达式。
生成的代码块引用的输入(例如,不止一次腹肌或马克斯块)。这可能会导致重复的复杂表达式和随后的退化的代码效率。
如果一块拒绝接受表达式一个输入端口,然后一块连接到输入端口是不允许输出一个通用的或简单的表达式。
要求输出一个常数表达式并不否认,因为没有性能损失一个常数表达式,和软件可以把参数的地址。
s函数API指定输入表达式验收
让你的s函数API提供了宏:
指定块的输入是否应该接受非常数的表达式(即琐碎或通用表达式)。
查询是否一块输入接受非常数的表达式。
默认情况下,块输入不接受非常数的表达式。
你应该叫你的宏mdlSetWorkWidths
函数。宏有这些参数:
SimStruct *年代
块的SimStruct:指针。int idx:
输入端口的从零开始的索引。bool值:
通过真实如果港口接受输入表达式;否则传入错误的。
宏用于指定块的输入是否应该接受一个非常数的表达式是:
空白ssSetInputPortAcceptExprInRTW (int portIdx SimStruct *年代,bool值)
相应的宏可以查询任何调用之前设定的状态ssSetInputPortAcceptExprInRTW
是:
bool ssGetInputPortAcceptExprInRTW (SimStruct * S, int portIdx)
拒绝请求块输出表达式
即使在一个特定的块的请求,它可以生成一个输出表达式,请求可以否认通用的原因。这些原因包括,但不限于:
输出表达式是重要的,并且有多个目的地的输出。
非常数的输出表达式,输出连接到至少一个目的地,不接受表达式的输入端口。
输出一个测试点。
输出被分配一个外部存储类。
输出必须使用全局数据存储(例如是一个合并的输入块或一块状态)。
输出信号是复杂的。
你不需要考虑这些通用的因素在决定是否使用表达式折叠为一个特定的块。然而,这些规则可以帮助当你检查生成的代码和分析的情况下表达折叠优化抑制。
表达折叠在TLC块实现
利用表达折叠、修改的TLC块实现内联函数,这样它通知仿真软件引擎是否产生或接受的表达金宝app
输入端口,在解释道s函数API指定输入表达式验收。
输出端口,如解释类别的输出表达式。
这个话题讨论需要修改TLC实现。
表达折叠合规
在BlockInstanceSetup
函数的功能,注册您的块符合表达折叠。否则,表达式折叠要求或允许在块的输出或输入将被禁用,并且将使用临时变量。
寄存器表达式折叠合规、TLC库函数的调用LibBlockSetIsExpressionCompliant(块)
中定义
。例如:matlabroot
/ rtw / c / tlc / lib / utillib.tlc
% %功能:BlockInstanceSetup = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = % % %函数BlockInstanceSetup(块,系统)无效% % % < LibBlockSetIsExpressionCompliant(块)> % % % endfunction
你可以有条件地禁用表达式折叠在一块的输入和输出通过有条件地调用这个函数。
如果覆盖一个薄块的实现提供的代码生成器使用您自己的实现,您不应该打前面的电话,直到你已经更新您的实现。
输出表达式
的BlockOutputSignal
一个标量函数用于生成代码输出表达式或nonscalar输出表达式的一个元素。如果你的块输出表达式,你应该添加一个BlockOutputSignal
函数。的原型BlockOutputSignal
是
%函数BlockOutputSignal(块,系统、portIdx ucv,液位控制阀,idx, retType)无效
的参数BlockOutputSignal
这些是:
块
:记录块产生一个输出表达式系统
:记录系统包含块portIdx
:从零开始的索引表达式的输出端口被生成ucv
:用户控制变量定义的输出元素正在生成的代码液位控制阀
:循环控制变量定义的输出元素正在生成的代码idx
:信号指数定义的输出元素正在生成的代码retType
:特征向量定义的信号类型访问所需:“信号”
指定了输出信号的内容或地址“SignalAddr”
指定的地址输出信号
的BlockOutputSignal
函数返回一个特征向量为输出信号或地址。特征向量应执行表达式的优先通过开放和终止括号,除非表达式由一个函数调用。一个表达式的地址只能返回常数表达式;这是参数的内存访问的地址。代码实现BlockOutputSignal
功能不断块:
% %功能:BlockOutputSignal = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = % %文摘:% %返回引用参数。这个函数* * % %可能使用的仿真软件优化块时输入输出的数据结构。金宝app% % %函数BlockOutputSignal(块,系统、portIdx ucv,液位控制阀,idx, retType)无效%开关retType %例“信号”%返回LibBlockParameter(价值、ucv液位控制阀,idx) %例“SignalAddr”%返回LibBlockParameterAddr(价值、ucv液位控制阀,idx) %默认%分配errTxt =“不支持的返回类型:% < retType > % < LibBlockReportError(块,errTxt) > % e金宝appndswitch % endfunction
代码实现BlockOutputSignal
函数关系操作符块:
% %功能:BlockOutputSignal = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = % %文摘:% %返回一个输出表达式。这个函数* * % %可能使用的仿真软件优化块时输入输出的数据结构。金宝app% % %函数BlockOutputSignal(块,系统、portIdx ucv,液位控制阀,idx, retType)无效%开关retType %例%分配logicOperator = ParamSettings“信号”。运算符%如果ISEQUAL (logicOperator " ~ = ") %分配op = " != " elseif ISEQUAL (logicOperator " = = ") %分配op = " = = " % %其他分配op = logicOperator % endif %分配情况= LibBlockInputSignal (0 ucv液位控制阀,idx) %分配u1 = LibBlockInputSignal (1 ucv液位控制阀,idx) %回报”(% <情况> % < op > % < u1 >)”%default %assign errTxt = "Unsupported return type: %" % %endswitch %endfunction
与多个输出表达式折叠块
当一块只有一个输出,输出
功能块的TLC文件叫做只有在输出端口不是一个表达式。否则,BlockOutputSignal
函数被调用。
如果一块有多个输出,输出
函数如果任何输出端口不是一个表达式。的输出
函数应该防备生成代码的输出端口表达式。这是通过保护部分对应的代码和调用各个输出端口LibBlockOutputSignalIsExpr ()
。
例如,考虑一个函数有两个输入和两个输出,
第一个输出,y0,等于两倍的第一个输入。
第二个输出,y1,等于第二个输入的四倍。
的输出
和BlockOutputSignal
函数的功能是代码摘录:
% %功能:BlockOutputSignal = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = % %文摘:% %返回一个输出表达式。这个函数* * % %可能使用的仿真软件优化块时输入输出的数据结构。金宝app% % %函数BlockOutputSignal(块,系统、portIdx ucv,液位控制阀,idx, retType)无效%开关retType %例“信号”%分配u = LibBlockInputSignal (portIdx、ucv, lcv idx) %例“信号”%如果portIdx = = 0%的回报”(2 * % u > <)%elseif portIdx == 1 %return "(4 * %)" %endif %default %assign errTxt = "Unsupported return type: %" % %endswitch %endfunction %% %% Function: Outputs ================================================= %% Abstract: %% Compute output signals of block %% %function Outputs(block,system) Output %assign rollVars = ["U", "Y"] %roll sigIdx = RollRegions, lcv = RollThreshold, block, "Roller", rollVars %assign u0 = LibBlockInputSignal(0, "", lcv, sigIdx) %assign u1 = LibBlockInputSignal(1, "", lcv, sigIdx) %assign y0 = LibBlockOutputSignal(0, "", lcv, sigIdx) %assign y1 = LibBlockOutputSignal(1, "", lcv, sigIdx) %if !LibBlockOutputSignalIsExpr(0) % = 2 * % ; %endif %if !LibBlockOutputSignalIsExpr(1) % = 4 * % ; %endif %endroll %endfunction
Expression-Folding-Compliant注释块
在过去,之前他们的输出代码块与评论的形式
/ * % <类型>块:% <名称> * /
expression-folding-compliant块时,上面所示的初始线是自动生成的。不包括评论块的TLC实现的一部分。注册使用的额外信息LibCacheBlockComment
函数。
的LibCacheBlockComment
函数接受一个特征向量作为输入,定义的评论,除了头,开幕式的最后换行单一或多行注释,拖车和结束。
下面的TLC代码说明了注册一个街区的评论。请注意函数的使用LibBlockParameterForComment
返回一个特征向量,适合一块评论,指定块参数的值。
% openfile commentBuf $ c(*)增益值:% < LibBlockParameterForComment(获得)> % closefile commentBuf % < LibCacheBlockComment(块,commentBuf) >