This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 编译器/TMS320F2.8377万D:无法让编译器发出RPT || MIN指令

Guru**** 2609955 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/639719/compiler-tms320f28377d-cannot-get-the-compiler-to-emit-a-rpt-min-instruction

部件号:TMS320F2.8377万D

工具/软件:TI C/C++编译器

我正在尝试让编译器生成有效的代码来查找最小的16位整数数组:

int array_min_i16 (const int *array,int num)

间隔最小值;

_nassert( num >0);

min =*array++;
同时(--num )

min =__min (min,*array++);
}

返回最小值;
}

 

这将生成程序集(可以从.compiler_opts标记中获取编译器选项)

;*******************************************************
;* TMS320C2000 C/C++ Codegen PC v 17.9 .0.STS *
;*创建日期/时间:2017年11月14日星期二16:56:02 *
;*******************************************************
compiler_opts --abi=coffabi --cla_support=cla1 --diag_wrap=off --float_support=fpu32 --hll_source=on --mem_model:code=flat --mem_model:data=large --object_format=coff --section_sizes=on --silit_version=28 --mu_none
ASGXAR2,FP
; 17.9 C:\\ccsv6\tools\compiler\ti-CGT-C2000_DCX.0.STS\bin\opt2000.exe --gen_opt_info=12000. --gen_opt_info=1 C:\\Users\\XXXX\\AppData\\Local\\Temp\\{B44A09E1-C4D6-4F83-8D85-016C0A54BF9C\}\A0524\Atemp\{A44A0546AFE_AFE_A05462\\\AFE#\A5\A5\A5\A5462\A5\A5\A5\A5\A5C\A5\A5\A5\A5BE\A5\A5\A5\A5BE\A5\A5BE\A5\A5\A5BE\A5</s>0546 0.5462万5462
; C:\\ccsv6\tools\compiler\ti-CGT-C2000_C2000<xmt-block0>2000 17.9 .STS\bin\ac2000.exe -@C:\\Users\\XXX\\AppData\\Local\\Temp\\{74F4C8A9-E322-45BA-9328-AB0817806698}</s>0817806698
.sect ".ti.ramfunc:_array_min_i16"
单击
.global _array_min_i16

;*******************************************************
;* FNAME:_array_min_i16 FR大小: 0*
;**
;*函数环境*
;**
;*函数属性*
;* 0参数,0自动,0 SOE *
;*******************************************************

_array_min_i16:
;***7------------------ min =*array;
;***8 --------------------------- 如果(!(--num))转到g7;
ADDB AL,#-1;[CPU_ALU]|8|
MOVZ AR6,AL;[CPU_ALU]|8|
MOV AL,*+XAR4[0];[CPU_ALU]|7|
MOV AH,AR6;[CPU_ALU]|7|
BF $C$L3,EQ;[CPU_ALU]|8|
;发生分支;[]|8|
;***10 --------------------------- D1美元 =编号和1;
;***7------------------ ++数组;
;***10 --------------------------- 如果(num < 2)转到G5;
ANDB AH,#1;[CPU_ALU]|10|
MOVZ AR7,AH;[CPU_ALU]|10|
ADDB XAR4,#1;[CPU_ALU]|7|
MOV AH,AR6;[CPU_FPU]|7|
CMBB AH,#2;[CPU_ALU]|10|
BF $C$L2,LT;[CPU_ALU]|10|
;出现分支;[]|10|
;***--------------- l1美元 =(num>>>1)-1;
;***--------------- #pragma must迭代(116383,1)
;***--------------- //以下循环按因子展开(2)
;***--------------- #pragma loop_flags(4102u)
ASR AH,1;[CPU_ALU]
ADDB AH,#-1;[CPU_ALU]
MOVZ AR6,AH;[CPU_ALU]
$C$L1:
;***--------------- G4:
;***10 --------------------------- min =__min (min,*array++);
;***10 --------------------------- min =__min (min,*array++);
;***8 --------------------------- 如果(--L1美元)!=(-1))转到G4;
最小Al,*XAR4++;[CPU_ALU]|10|
最小Al,*XAR4++;[CPU_ALU]|10|
Banz $C$L1,AR6-;[CPU_ALU]|8|
;发生分支;[]|8|
$C$L2:
;***--------------- G5:
;***--------------- 如果(d1美元<=0)转到G7;
MOV AH,AR7;[CPU_ALU]
BF $C$L3,Leq;[CPU_ALU]
;发生分支;[]
;未滚动循环的剥离循环迭代:
;***10 --------------------------- min =__min (min,*array);
;***--------------- G7:
;***13--------------- 返回最小值;
最小Al,*+XAR4[0];[CPU_ALU]|10|
$C$L3:
LRETR;[CPU_ALU]
;出现返回;[]

我无法让编译器产生更高效的  

_array_min_i16:
SubB ACC,#2
MOV AH,AL
MOV AL,*XAR4++
RPT AH
||最小AL,*XAR0++;
LRETR;

如何让编译器生成更优化的函数版本? 是否缺少编译器开关(可能是最大不间断序列)?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    当我使用C2000编译器版本RPT||MIN时,如果使用汇编文件中显示的编译器选项加上-O2,我将得到17.9。

    % cl2000 -s -O3 foo.c --abi=coffabi --cla_support=cla1 --diag_wrap=off --float_support=fpu32.
    --mem_model:code=flat --mem_model:data=large --object_format=coff --section_sizes=on
    --silicon_version=28 --symdebug:none --tmu_support=tmu0
    
    % egrep 'rpt|min' foo.asm
    报告 AR5
    || 最小 啊,*XAR4++ ;[CPU_ALU]|10| 

    我猜您使用的是装配体文件中未显示的附加选项,这会影响循环。  请向我展示您的完整命令行选项。  最好的做法是重建此文件,然后向我发送整个生成控制台窗口。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我已通过在CCS中创建新项目来复制您的输出,并使用了默认的“发行版”生成选项(启用了keep ASM)。

    我发现优化级别对编译器输出没有影响。

    我发现'优化速度'(opt_of_speed)选项是问题的原因。 将opt_for speed从2更改为3会引起从RPT || min更改为未滚动循环。

    几年前,我在C6000编译器上被这种情况所咬过,被告知opt_of_speed循环展开通过发生在指令优化器之前。 此时,指令优化器无法将未回滚的循环优化回单循环内核,或者明确告知不这样做。

    我可以确认,即使opt_for_speed设置为5,#pragma unroll(1)也能实现所需的输出。

    这将打开以下问题:opt_for speed是一个有用的选项还是我应该保留为默认选项?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    它对某些基准很有用,但正如他们所说,您的年龄可能会有所不同。 我没有意识到这种特殊的皱纹。 在这种情况下,我打赌卸载器被RPTB指令上的最小循环大小所阻止。 为您的代码做最好的事情;在这种情况下,我建议保留unroll(1) pragma,然后尝试使用--opt_for_speed的设置。