ZHCUCO7B December   2024  – November 2025 F29H850TU , F29H859TU-Q1

 

  1.   1
  2.   摘要
  3.   商标
  4. 1引言
  5. 2性能优化
    1. 2.1 编译器设置
      1. 2.1.1 启用调试和源代码交叉列
      2. 2.1.2 优化控制
      3. 2.1.3 浮点数学
      4. 2.1.4 定点除法
      5. 2.1.5 单精度与双精度浮点
      6. 2.1.6 链接时优化 (LTO)
    2. 2.2 存储器设置
      1. 2.2.1 从 RAM 执行代码
      2. 2.2.2 从闪存执行代码
      3. 2.2.3 数据放置
    3. 2.3 代码结构和配置
      1. 2.3.1 内联
      2. 2.3.2 内联函数
      3. 2.3.3 易失性变量
      4. 2.3.4 函数参数
      5. 2.3.5 启用更广泛的数据访问
      6. 2.3.6 自动代码生成工具
      7. 2.3.7 准确剖析代码
    4. 2.4 应用代码优化
      1. 2.4.1 SDK 优化库
      2. 2.4.2 使用库优化代码尺寸
      3. 2.4.3 C29 特别指令
      4. 2.4.4 C29 并行性
      5. 2.4.5 首选 32 位变量和写入
      6. 2.4.6 编码风格及其对性能的影响
  6. 3参考资料
  7. 4修订历史记录

编码风格及其对性能的影响

开发人员编写 C 代码的方式会对性能产生影响。本节说明可能发生这种情况的具体示例场景。

  • 使用循环时,性能可能因循环计数器是固定值还是变量而有所不同。如果是固定值,则编译器完全了解循环,并可确定最大限度发挥性能的策略:无论这是否意味着展开循环、对循环进行软件流水线处理等。例如,对于矩阵乘法,如果在循环中指定矩阵行和列大小,而不是将其作为函数参数传入,则性能将得到显著提升。
  • 在某些情况下,将多个独立循环合并为一个循环可以提升性能。下面的第一个代码块会生成次优代码,第二个代码块的优化程度更高。
uint8_T Bit_Manipulation_Test_Case(void) 
{ 
uint32_T result; 
uint32_T i; 
uint8_T valid; 
result = 0u; 
valid = TC_OK; 
i = 0u; 
/* Or Test Case */
for(i=0; i<BIT_MANIPULATION_ARRAY_SIZE; i++) 
{ 
    result = (Swc1_Bit_Manipulation.Operand_A[i] | Swc1_Bit_Manipulation.Operand_B[i]); 
    if(result != Swc1_Bit_Manipulation.Result_Or[i]) 
    { 
        valid = TC_NOK; 
    } 
} 
/* And Test Case */
for(i=0; i<BIT_MANIPULATION_ARRAY_SIZE; i++) 
{ 
    result = (Swc1_Bit_Manipulation.Operand_A[i] & Swc1_Bit_Manipulation.Operand_B[i]); 
    if(result != Swc1_Bit_Manipulation.Result_And[i]) 
    { 
        valid = TC_NOK; 
    } 
} 
/* Xor Test Case */
for(i=0; i<BIT_MANIPULATION_ARRAY_SIZE; i++) { 
    result = (Swc1_Bit_Manipulation.Operand_A[i] ^ Swc1_Bit_Manipulation.Operand_B[i]); 
    if(result != Swc1_Bit_Manipulation.Result_Xor[i]) { 
        valid = TC_NOK; 
    } 
} 
    return valid; 
}
uint8_T Bit_Manipulation_Test_Case(void) 
{ 
uint32_T result_or,result_and,result_xor; 
uint32_T i; 
uint8_T valid; 
result_or = 0u; 
result_and = 0u; 
result_xor = 0u; 
valid = TC_OK; 
i = 0u; 
/* Or, And, Xor Test Case */ 
for(i=0; i<BIT_MANIPULATION_ARRAY_SIZE; i++) 
{ 
    result_or = (Swc1_Bit_Manipulation.Operand_A[i] | Swc1_Bit_Manipulation.Operand_B[i]); 
    if(result_or != Swc1_Bit_Manipulation.Result_Or[i]) 
    { 
        valid = TC_NOK; 
    } 
    result_and = (Swc1_Bit_Manipulation.Operand_A[i] & Swc1_Bit_Manipulation.Operand_B[i]); 
    if(result_and != Swc1_Bit_Manipulation.Result_And[i]) 
    { 
        valid = TC_NOK; 
    } 
    result_xor = (Swc1_Bit_Manipulation.Operand_A[i] ^ Swc1_Bit_Manipulation.Operand_B[i]); 
    if(result_xor != Swc1_Bit_Manipulation.Result_Xor[i]) 
    { 
        valid = TC_NOK; 
    } 
} 
return valid; 
}
  • 此外,如果条件语句涉及从存储器加载或访问全局变量,则在可能的情况下将它们预加载到局部变量中可能会有所帮助。这样可以更多地使用 C29 CPU 上的更宽寄存器集。它还可防止从存储器加载值并立即对其执行条件检查时出现流水线停顿。下面的第一个代码块会生成次优代码,第二个代码块的优化程度更高。

// Variables are globals
if(xx ==FALSE) 
{ 
    A = b * c + d; 
    E = f * c + d;
    if(dd > high) 
    { 
        D = high; 
    } elseif (dd < low) {
        if(kk == RUN)
        { 
            D = low; 
        } else { 
            D = dd; 
        } 
    } else { 
        D=dd; 
    } 
}
// Local copies of globals
float b_temp=b, c_temp=c, d_temp=d, f_temp=f, high_temp=high, low_temp=low, dd_temp=dd, kk_temp=kk, D_temp=D, g_temp=g, h_temp=h;
if(xx==FALSE) 
{ 
    A = b_temp * c_temp + d_temp; 
    E = f_temp * c_temp + d_temp;
    if(dd_temp > high_temp) 
    { 
        D_temp = high_temp; 
    } elseif (dd_temp < low_temp) {
        if(kk_temp == RUN)
        { 
            D_temp = low_temp; 
        } else { 
            D_temp = dd_temp; 
        } 
    } else { 
        D_temp=dd_temp; 
    } 
}