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.

TMS320C6748: DSPLIB点乘效率波动

Part Number: TMS320C6748

测试环境:ccs10.4,编译优化级别o3dsplib版本3.4 for c674x,编译器为TI7.4.24

所有代码和数据均放在L2RAM中,L1P按默认值做cache用,L1D按默认值是做RAM用

现象:DSPF_sp_dotprod函数涉及两组float的相乘,两组系数均为32字节对齐时,测试将1024阶点乘执行1M次,测试结果表明其效率存在波动。


以下是dsplib中点乘函数的c代码:

#pragma CODE_SECTION(DSPF_sp_dotprod, ".text:optimized");

#include "DSPF_sp_dotprod.h"

float DSPF_sp_dotprod(const float * x, const float * y, const int nx)
{
    int i;
    float sum = 0;

    _nassert(nx > 0);
    _nassert(nx % 8 == 0);
    _nassert((int)x % 8 == 0);
    _nassert((int)y % 8 == 0);
    
    for(i = 0; i < nx; i++)    
      sum += x[i]*y[i];
    
    return (sum);
}


测试用代码:

//#pragma DATA_SECTION(".far:optimized");
#pragma DATA_ALIGN(32)
float	x1[1024+100];

//#pragma DATA_SECTION(".far:optimized");
#pragma DATA_ALIGN(32)
float	x2[1024+100];

printf("==DotProd V0 test!==\n");
	for(cur = 0; cur <32; cur++)
	{
		mTC.StartTimer();
		for(i=0; i<cycles; i++)
		{
			sum+=dot_product_v0_align8(x1+cur<<1,x2, 1024);//起点每次移动2元素
		}
		mTC.StopTimer();
		printf("cur=%d, ",cur);
		mTC.PrintResult();
	}


测试结果:

==DotProd V0 test!==
cur=0, 2.355 s @456MHz.
cur=1, 1.231 s @456MHz.
cur=2, 1.232 s @456MHz.
cur=3, 1.231 s @456MHz.
cur=4, 2.355 s @456MHz.
cur=5, 1.231 s @456MHz.
cur=6, 1.232 s @456MHz.
cur=7, 1.231 s @456MHz.
cur=8, 2.355 s @456MHz.
cur=9, 1.231 s @456MHz.
cur=10, 1.232 s @456MHz.
cur=11, 1.231 s @456MHz.
cur=12, 2.355 s @456MHz.
cur=13, 1.231 s @456MHz.
cur=14, 1.232 s @456MHz.
cur=15, 1.231 s @456MHz.
cur=16, 2.355 s @456MHz.
cur=17, 1.231 s @456MHz.
cur=18, 1.232 s @456MHz.
cur=19, 1.231 s @456MHz.
cur=20, 2.355 s @456MHz.
cur=21, 1.231 s @456MHz.
cur=22, 1.232 s @456MHz.
cur=23, 1.231 s @456MHz.
cur=24, 2.355 s @456MHz.
cur=25, 1.231 s @456MHz.
cur=26, 1.232 s @456MHz.
cur=27, 1.231 s @456MHz.
cur=28, 2.355 s @456MHz.
cur=29, 1.231 s @456MHz.
cur=30, 1.232 s @456MHz.
cur=31, 1.231 s @456MHz.

所以,为什么该代码在x和h都是32字节对齐的情况下,会出现效率明显的下降呢?按我推断是和储存器访问冲突有关,那么有什么办法可以消除此问题呢

另外,是否有不要求8字节对齐的高效点乘函数呢,我看dsplib里面只提供了8字节对齐的版本,如果我想每次将起点移动4字节的话,dsplib的点乘就不工作了

虽然我手写了一个,但是其效率跟库函数在32字节对齐处的效率相当,是否有办法进一步优化呢

float dot_product_v1(const float *restrict x, const float *restrict h, const unsigned int length)
{
  int i;
  float sum1 = 0, sum2 = 0;

	_nassert(length > 0);
  _nassert(length % 4 == 0);
//	//数据已经对齐,提示编译器优化
//事实上float数组本身都是4字节对齐的,实测加不加效率相同
//	_nassert(((int)(x) & 0x3) == 0);
//	_nassert(((int)(h) & 0x3) == 0);

#pragma MUST_ITERATE(,1024,2)//最小8(去除后可使用分段),最大1024,执行次数是2的倍数【即滤波器长度为4的倍数】
  for (i = 0; i < length; i+=2)
  {
			sum1 += x[i]*h[i];
			sum2 += x[i+1]*h[i+1];
  }
	return sum1 + sum2;
}