ZHCU881D May 2020 – May 2024
编译器有时采用头文件中定义的函数,并将代码放在调用位置。这样,允许在封闭式循环中形成软件流水线作业,从而提高性能。编译器也可以这样做来消除调用函数和从函数返回的成本。
在下例中,add_and_saturate_to_255()
函数对两个值求和,如果总和超过 255,则将总和限制为 255。此函数是从 inlining.cpp
中的函数调用的,该函数通过预处理器的 #include 指令包含 inlining.h
文件。
// inlining.cpp
// Compile with "cl7x -mv7100 --opt_level=3
// --debug_software_pipeline --src_interlist"
#include "inlining.h"
void saturated_vector_sum(int * restrict a, int * restrict b,
int * restrict out, int n)
{
#pragma MUST_ITERATE(1024,,)
#pragma UNROLL(1)
for (int i = 0; i < n; i++)
{
out[i] = add_and_saturate_to_255(a[i], b[i]);
}
}
// inlining.h
int add_and_saturate_to_255(int a, int b)
{
int sum = a + b;
if (sum > 255) sum = 255;
return sum;
在此例中,编译器将内联对 add_and_saturate_to_255()
的调用,因此可执行软件流水线作业。您可以通过查看生成的汇编文件底部确定是否执行了内联。此处,编译器放置入了注释,说明 add_and_saturate_to_255()
已内联。请注意,由于 C++ 名称已改编,故函数的标识符也已被修改。
;; Inlined function references:
;; [0] _Z23add_and_saturate_to_255ii
在生成的汇编代码中也可以看到内联,因为循环中没有针对函数的调用指令。事实上,由于内联(因而消除了对函数的调用),循环可以进行软件流水线。 如果在循环中调用了另一个函数,则不会发生软件流水线。 请注意,由于代码大小的问题,并非每个可内联的调用都会自动内联。有关内联的更多信息,请参阅 C7000 优化编译器用户指南。
;*----------------------------------------------------------------------------*
;* SINGLE SCHEDULED ITERATION
;*
;* ||$C$C44||:
;* 0 TICK ; [A_U]
;* 1 SLDW .D1 *D1++(4),BL0 ; [A_D1] |5|
;* 2 SLDW .D2 *D2++(4),BL1 ; [A_D2] |5|
;* 3 NOP 0x5 ; [A_B]
;* 8 ADDW .L2 BL1,BL0,BL1 ; [B_L2] |5|
;* 9 VMINW .L2 BL2,BL1,B0 ; [B_L2] |5|
;* 10 STW .D1X B0,*D0++(4) ; [A_D1] |5|
;* || BNL .B1 ||$C$C44|| ; [A_B] |11|
;* 11 ; BRANCHCC OCCURS {||$C$C44||} ; [] |11|
;*----------------------------------------------------------------------------*