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.

[参考译文] 编译器/C6000-CGT:软件流水线循环问题

Guru**** 2595770 points


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

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/968568/compiler-c6000-cgt-software-pipelined-loop-problem

器件型号:C6000-CGT

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

您好!

我有一个函数、用于根据从多个 ADC 通道接收到的信号估算简单的协方差矩阵。 在-O3处优化代码时、启用软件流水线、并使我的协方差矩阵的输出偏离预期值。 有趣的是、偏差仅发生在 m 索引循环的第三次到第七次迭代上。

void calc_B (float* restrict B、int32_t n_chan、int32_t n_samples、float* samples)
{
int32_t* restrict 偏移1;
int32_t* restrict 偏移2;
int32_t idx;
int64_t samples1;
int64_t SAMPLES2;
int64_t samples3;
int64_t samples4;
int32_t b_idx;
int64_t ltmp;
int32_t itmp;
浮点刻度;
浮点 ACC1;
浮点 ACC2;
浮点 ACC3;
float acc4;
int32_t n;
int32_t m;

//快于1/n_chirps
scale =沉淀(n_samples);

b_idx = 0;

对于(n = 0;n < n_CHAN;n++)
{
Offset1 =&input_samples[n_samples* n];

ACC1 = 0.0f);
ACC2 = ACC1;
ACC3 = ACC2;
acc4 = ACC3;

//第一个内环计算矩阵对角线元素
对于(idx = 0;idx < n_samples;idx += 8)
{
samples1 =_amem8 (偏移1 + idx);
功能 =_hill (samples1);
lltmp=_mpy2ll (itmp、itmp);
功能 =_loll (samples1);
lltmp =_dadd (lldmp、_mpy2ll (itmp、itmp));
ACC1 +=_hill (lltmp)+_loll (lltmp);

SAMPLES2 =_amem8 (偏移1 + idx);
功能 =_hill (SAMPLES2);
lltmp=_mpy2ll (itmp、itmp);
功能 =_loll (SAMPLES2);
lltmp =_dadd (lldmp、_mpy2ll (itmp、itmp));
ACC2 +=_hill (lltmp)+_loll (lltmp);

samples3 =_amem8 (偏移1 + idx);
功能 =_hill (samples3);
lltmp=_mpy2ll (itmp、itmp);
功能 =_loll (samples3);
lltmp =_dadd (lldmp、_mpy2ll (itmp、itmp));
ACC3 +=_hill (lltmp)+_loll (lltmp);

samples4 =_amem8 (偏移1 + idx);
功能 =_hill (samples4);
lltmp=_mpy2ll (itmp、itmp);
功能 =_loll (samples4);
lltmp =_dadd (lldmp、_mpy2ll (itmp、itmp));
acc4 +=_hill (lltmp)+_loll (lltmp);
}

b[b_idx+]= Scale *(ACC1 + ACC2 + ACC3 + acc4);

//对角线条目(右上角三角形)
对于(m = n + 1;m < n_chan;m++)
{
Offset2 =&input_samples[n_samples* m];
ACC1 = 0.0f;
ACC2 = ACC2;

对于(idx = 0;idx < n_samples;idx += 4)
{
samples1 =_amem8 (偏移1 + idx);
SAMPLES2 =_amem8 (偏移2 + idx);
功能 =_hill (SAMPLES2);
lltmp =_mpy2ll (_hill (samples1)、itmp);
功能 =_loll (SAMPLES2);
lltmp =_dadd (lldmp、_mpy2ll (_loll (samples1)、itmp);
ACC1 +=_hill (lltmp)+_loll (lltmp);

samples3 =_amem8 (偏移1 + idx + 2);
samples4 =_amem8 (偏移2 + idx + 2);
功能 =_hill (samples4);
lltmp =_mpy2ll (_hill (samples3)、itmp);
功能 =_loll (samples4);
lltmp =_dadd (lldmp、_mpy2ll (_loll (samples3)、itmp);
ACC2 +=_hill (lldmp)+_loll (lldmp);
}

b[rn_idx++])=比例*(ACC1 + ACC2);
}
}

我已经阅读了编译器指南中有关使用 volatile 关键字的建议(https://www.ti.com/lit/ug/sprui04c/sprui04c.pdf#page=65 第4.4.2节)。 使 ACC1和 ACC2变得易失性足以解决数字问题、但会导致性能下降(速度降低~25%)、这是无法容忍的。 读取生成的汇编代码看起来会使 ACC1/2变得易失性、从而破坏内部环路流水线。

为什么软件流水线循环只会干扰某些 m 索引循环值?

--柯蒂斯

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

    对于包含有问题函数 的源文件、请按照文章如何提交编译器测试用例中的说明进行操作。

    谢谢、此致、

    乔治

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

    好的、明天早上我将提交预处理的文件。