TI中文支持网
TI专业的中文技术问题搜集分享网站

c6678 运行速度很慢

各位大神好,

       我最近想做使用DSPC6678来实现一个算法的实时性,用到了CCS8.3 win10 c6678的板子,由于对DSP性能还不熟悉暂时只用一个核去做了处理。

       但是发现在vs中同样的.c程序只用25s,而在DSP中用TSCL检测出来(release下)需要3000s,大大超出了我的遇期(目的是想要减少时间啊)。

       代码没有改动,只是代码中申请使用很多动态数组,一维,二维,三维都有用到,算法中也有很多子函数,用到了很多循环。用了系统自带的C6678的.cmd文件。想向大家请教一下是哪里还需要改设置吗,为什么时间会差距这么大?     以下是我的.cmd文件和主函数的代码。十分感谢~~

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include "math.h"
#include "time.h"
#include "c6x.h"


// 读取到的图像,存储到DDR3中
#pragma DATA_SECTION(num,".imageData")
#pragma DATA_ALIGN(num, 256)// 256字节对齐
double num[3];

#define inner_win_size 11
#define out_win_size 33

void readimagedata(double *fp, int H, int W, int Dim, double ***array);
double ***padarray(double ***h, int H, int W, int Dim);
void RXD_function(double ***h, double *mean, double **inv, double **RXD, int Dim, int i, int j);
double **sequential_inv(double **cov, double **aug, int num, int row, int col, char a);
void row_cycle(double ***array, double **aug_plus, double **aug_subtract, double **cov, double *mean, double ***inv_cov_1, double **mean_1, int Dim, int W, double ***h, double **RXD);
void col_cycle(double ***array, double **aug_plus, double **aug_subtract, double **cov, double *mean, double ***inv_cov_1, double **mean_1, int H, int W, int Dim, double ***h, double **RXD);
void cov_inv(double **m, int H, int Dim, double *mean, double lambda, double **cov);
void Firstinv(double ***array, int Dim, double **temp, double *mean, double **cov);
double*** Malloc3DActiveArray(int x, int y, int z);
void Free3DActiveArray(double *** pArr, int x, int y);
double** Malloc2DActiveArray(int x, int y);
void Free2DActiveArray(double ** pArr, int x);

int main()
{FILE *fid;fid = fopen("E:\\ccs_workspace\\fast_rx_s_2\\test_double.dat", "rb");if (fid == NULL){printf("error on open file!\n");}printf("test console!\n");double num[3];fread(&num, sizeof(double), 3, fid);int H = num[0];int W = num[1];int Dim = num[2];double *pos = (double*)malloc(sizeof(double)*H*W*Dim);fread(pos, sizeof(double), H*W*Dim, fid);fclose(fid);printf("pos is ok!\n");double *** h = NULL;h = Malloc3DActiveArray(H, W, Dim);readimagedata(pos, H, W, Dim, h);fclose(fid);free(pos);unsigned long long t1,t2;TSCH=0;TSCL=0;t1=_itoll(TSCH,TSCL);//t1=TSCL;printf("h is ok!\n");double *** array = NULL;array = Malloc3DActiveArray(H + out_win_size-1, W + out_win_size-1, Dim);array = padarray(h, H + out_win_size-1, W + out_win_size-1, Dim);double **a = NULL, **cov = NULL;double *mean = (double *)malloc(Dim * sizeof(double));a = Malloc2DActiveArray(8 * inner_win_size*inner_win_size, Dim);cov = Malloc2DActiveArray(Dim, Dim);Firstinv(array, Dim, a, mean, cov);double ***inv_cov_1 = NULL;inv_cov_1 = Malloc3DActiveArray(Dim, Dim, W);double **mean_1 = NULL;mean_1 = Malloc2DActiveArray(Dim, W);int i, j;for (i = 0; i < Dim; i++){for (j = 0; j < Dim; j++){inv_cov_1[i][j][0] = cov[i][j];}mean_1[i][0] = mean[i];}double **RXD = NULL;RXD = Malloc2DActiveArray(H, W);RXD_function(h, mean, cov, RXD, Dim, 0, 0);printf("RXD_1 is ok!\n");double **aug_plus = NULL;aug_plus = Malloc2DActiveArray(4 * inner_win_size + 1, Dim);double **aug_subtract = NULL;aug_subtract = Malloc2DActiveArray(4 * inner_win_size + 1, Dim);row_cycle(array, aug_plus, aug_subtract, cov, mean, inv_cov_1, mean_1, Dim, W, h, RXD);printf("row_cycle is ok!\n");col_cycle(array, aug_plus, aug_subtract, cov, mean, inv_cov_1, mean_1, H, W, Dim, h, RXD);t2=_itoll(TSCH,TSCL);//t2=TSCL;printf("cycle = %lld \n",t2-t1);printf("all complete!");FILE *fid1;fid1 = fopen("RXD_double_r.dat", "wb");if (fid1 == NULL){printf("error on open wfile!\n");}double *f = (double*)malloc(sizeof(double)*Dim*Dim);for (i = 0; i < H; i++){for (j = 0; j < W; j++){f[i*H + j] = RXD[i][j];}}fwrite(f, sizeof(double), H*W, fid1);fclose(fid1);Free3DActiveArray(h,H,W);Free3DActiveArray(array, H + out_win_size - 1, W + out_win_size - 1);Free2DActiveArray(a,8*inner_win_size*inner_win_size);Free2DActiveArray(cov,Dim);Free3DActiveArray(inv_cov_1,Dim,Dim);Free2DActiveArray(mean_1,Dim);Free2DActiveArray(RXD,H);Free2DActiveArray(aug_plus, 4 * inner_win_size + 1);Free2DActiveArray(aug_subtract, 4 * inner_win_size + 1);return 0;
}
.cmd文件
MEMORY
{LOCAL_L2_SRAM:  o = 0x00800000 l = 0x00080000/* 512kB LOCAL L2/SRAM */LOCAL_L1P_SRAM: o = 0x00E00000 l = 0x00008000/* 32kB LOCAL L1P/SRAM */LOCAL_L1D_SRAM: o = 0x00F00000 l = 0x00008000/* 32kB LOCAL L1D/SRAM */SHRAM:o = 0x0C000000 l = 0x00400000/* 4MB Multicore shared Memmory */EMIF16_CS2:o = 0x70000000 l = 0x04000000/* 64MB EMIF16 CS2 Data Memory */EMIF16_CS3:o = 0x74000000 l = 0x04000000/* 64MB EMIF16 CS3 Data Memory */EMIF16_CS4:o = 0x78000000 l = 0x04000000/* 64MB EMIF16 CS4 Data Memory */EMIF16_CS5:o = 0x7C000000 l = 0x04000000/* 64MB EMIF16 CS5 Data Memory */DDR3:o = 0x80000000 l = 0x80000000/* 2GB CE0 and CE1 external DDR3 SDRAM */
}
 
SECTIONS
{.text>  SHRAM.stack>  DDR3.bss>  SHRAM.cio>  SHRAM.const>  SHRAM.data>  SHRAM.switch>  SHRAM.sysmem>  DDR3.far>  SHRAM.args>  SHRAM.ppinfo>  SHRAM.ppdata>  SHRAM/* COFF sections */.pinit>  SHRAM.cinit>  SHRAM/* EABI sections */.binit>  SHRAM.init_array>  SHRAM.neardata>  SHRAM.fardata>  SHRAM.rodata>  SHRAM.c6xabi.exidx  >  SHRAM.c6xabi.extab  >  SHRAM.imagedata>  DDR3
}

Ryan BL:

你们需要个DSP优化,无论从实现上的优化还是工程的优化。
最简单来说,在编译的时候加上-o[0-3]优化,会有比较大的速率提升;
如果你们在成都,那么我刚好打算换工作了,可以联系哟:)

Shine:

回复 Ryan BL:

先用优化选项-O3优化一下代码。

user5179571:

回复 Shine:

您好,我在Properties->Bulid->C6000 Complier->Optimization 中将Optimization level的选项改成了-O3,不知道这样修改是不是对的。但是程序在读取数据时出错,读取的num[0],num[1],num[2]是正确的,但是变为int型的H,W,Dim就会出错,加上强制转换也不行。修改了优化选项,只有-O0不会出错,但速度几乎没有提升。(看到H是正确的,W,Dim的地址显示在寄存器)请问这个问题应该怎么解决呢?急求,谢谢。

Tao_LL:

1.将cmd中system从DDR改为SHRAM
2.用内敛指令
3.预编译

Ryan BL:

回复 Tao_LL:

能放SHRAM或Local—L2的尽量往里面放,高速内存很重要;
少用malloc,建议直接固定专用内存;
循环优化是关键,三维这种要尽可能杜绝,尽量使用一维;
计时中间调用的算法,里面尽可能少打印,确实需要可以使用bios的system.min的打印到ROV,不要直接打印到控制台;
至于你说的出错,这个比较麻烦点,经常是编译器没太理解到你的意图或数据依赖关系给过分优化了,尝试换种写法试试;

user5179571:

回复 Ryan BL:

十分感谢。我尝试了用一维数据去做,但是貌似还是在malloc遇到了问题。因为我需要处理不同大小的数据集,所以感觉只能用malloc去分配内存,因为我预先不知道大小是多少。但是现在,在第一部为pos分配内存时就特别慢(起初我还以为是fread的原因,我还特意换成了二进制的数据文件),所以我现在想请教malloc该如何使用,申请过程都要半小时以上是什么 原因呢?我现在跑的数据是64*64*169的,其他数据更大。之前把system放到DDR中也是因为申请数组过大。现在将-heap和-stack改成0x300000,-system放到了SHRAM中。以上情况是基于此出现的,之前遇到的问题换了写法解决了。谢谢~

user5179571:

回复 Tao_LL:

您好,谢谢您的回复。我将system放到DDR中是因为要动态分配的数据很大,SHRAM中怕放不下。

您说的内敛指令和预编译(#pragma?)可以详细一点说怎么用吗,或者您有没有合适的学习资料可以推荐我使用?十分感谢~~

现在malloc貌似是最耗时的步骤,将申请64*64*169的内存需要耗费半小时,将stack和heap改为0x300000以后(之前是0x10000000)fread读取不进去了。

Ryan BL:

回复 user5179571:

按照你要用的最大,定义个放在MSMC或LL2的内存,这个仅是普遍的通用情况;
实际考虑数据应该是一部分一部分处理的,一般是把即将要处理的数据ping/pong倒换,处理完一块用EDMA做背景传输,而后处理另一块,在处理结果搬移完后使用EDMA级联个下一次要处理的数据。这个属于整个数据流上的优化;
然后就是,file操作是很费时的,因为jtag速率受限,而且那块会占用大量的dsp时间,建议直接把这个文件使用Memory Browser导入内存再处理,因为你最终处理数据,这个数据也应该是SRIO或网络或PCIE通道获取的。

Ryan BL:

回复 user5179571:

应该是笔误,是“内联”,导入“c6x.h" 头文件,你使用的运算尽可能优化成使用里面定义的接口;

看不懂或不明白是什么意思的话,这里有:

赞(0)
未经允许不得转载:TI中文支持网 » c6678 运行速度很慢
分享到: 更多 (0)