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.

c6748的运算速度如何提高

各位大神,我现在想充分调用C6748的速度,456MHZ,我自己写了一段for循环,在仿真器的debug模式下,测10W次的乘法、除法、sin运算,引出波形用示波器周期计时。下面是for循环代码。

float a=1.0,b=0.0,c=1.0;
int i;
while(1)
{

for(i=0;i<100000;i++)
   { b=sin(a);   //b=sinsp(a);
   }
    GPIOPinWrite(SOC_GPIO_0_REGS, 110, GPIO_PIN_HIGH); // D4 亮
  for(i=0;i<100000;i++)
{ b=sin(a); //b=sinsp(a);
}

   GPIOPinWrite(SOC_GPIO_0_REGS, 110, GPIO_PIN_LOW); // D4 灭

}

下面是用时:

运算函数

耗时(ms

未采取任何措施

使用浮点计数库

理论值

浮点=浮点*浮点

    52.6ms a=b*c

        没有找到乘法函数

1/4.56*2=0.1

浮点=浮点\浮点

    55ms   a=b/c

     38.75ms

   divsp(b,c)

 

浮点=sin(浮点)

    204ms a=sin(b)

     39.2ms  a=sinsp(b)


现在我的计算速度远远没有发挥出来,我归结了几点我的问题,1、CPU并行度是否要提高。 2、程序是否要优化。 3、库函数的引用是否正确 

  • 对于大量计算的代码,尤其是for 循环比较多的情况,加上O3后一般会有一定提升。

    有兴趣的话可以看一下优化资料。
    http://processors.wiki.ti.com/index.php/TMS320C6000_DSP_Optimization_Workshop

  • 您好,请问2 SP x SP SP Per Clock,这句话是不是说理论上每个cpu cycle可以计算两次浮点乘法?

  • 楼主,好像不一定。你如果打断了流水线之后会慢很多。

  • lin li18 说:

    您好,请问2 SP x SP SP Per Clock,这句话是不是说理论上每个cpu cycle可以计算两次浮点乘法?

    每条汇编指令都有固定的cpu cycle,具体看汇编指令手册。
    http://www.ti.com/lit/ug/sprufe8b/sprufe8b.pdf 

  • 流水线怎么打断?DSP不就是流水线工作么?

  • 我用clock测了一下,一个a=b*c单精度的要132个cycle

  • 很多类似这种乘加的运算有库函数支持的,另外流水很容易打断,你用if else或者for就打断了

  • 我加了-O3后我看反汇编,发现汇编代码直接跳过了整个for循环,请问这是怎么回事

  • 您好,我改了cmd文件后,现在用时减到5ms,每进行一次乘法运算用了足足60个cpu cycle。可是我在datasheet里看到两句话:Up to 3648/2746 C674x MIPS/MFLOPS;  2 SP x SP → SP Per Clock;  这么快的理论速度是怎么达到的呢?
    为什么我进行一次乘法就需要这么多的cycle呢,我查了汇编指令手册对于乘法cycle是+1把?(可能理解错了)

    此外我想要进行优化,-O0的时候就把for循环里的乘法运算直接优化没了(-O1到-O3也是)。这种情况需要怎么做呢,迫切需要您的回复。

  • 你好,你程序的运行是在ddr里面还是在cpu的L2里面。运行在不同的环境下这两个运行的速度差异会很大的。我觉得你可能程序跑在外部存储器里面。

    另外我建议楼主还是使用dsplib里面的库函数比如“DSPF_sp_w_vec”或者短指令来取代,这个可以在ti的官网上下载。即使用了这些指令,可能速度也达不到你的要求,需要你在流水线上进行优化,这个就比较花时间了。需要你把计算的变量进行对齐,对循环操作进行优化。我发一个链接给你

    http://www.deyisupport.com/files/m/c6000_multicore/default.aspx

    这里面的文档很全面,你找一下优化相关的文档。

  • 您好,首先谢谢您了。我现在是在L2里运行的,另外我现在试验的a=b*c并没有库函数吧?至于优化,我正在学习中,您给我的材料我会仔细看的。

  • 你是怎么看运行时间的?用的仿真器吧,那个有可能不是太准。你最好看下整个循环的时间再除以循环的次数。用dsp的心跳寄存器TSCH或者TSCL看。

  • 我用示波器看的,我在for循环结束后在GPIO输出一个电平,用示波器测的时间,至于每个a=b*c;我用的profile clock,设置断点单步走,每个a=b*c用60个cpu cycle

  • 如果都在L2,优化级别又高。一个单精度浮点应该用不了那么长时间。你能不能把算法写复杂一些,单步运算看clock不是特别准。

  • 我是用的是OMAPL138芯片,现在每次是在LINUX环境下使用MAKEFILE编译双核代码,请问我如果想使用O3优化选项的话应该怎么操作啊?

  • 还是用dsp的心跳寄存器TSCH或者TSCL看。你设置一个全局变量,在要观察的地方把TSCH或者TSCL保存一下。运行完以后你剪一下就知道运行了多少个周期了
  • 您好,可以问下您是怎么把代码放在L2中运行的嘛?是在特定程序添加关键字嘛?我现在想把部分代码放在L2中运行以提高执行效率,望提供帮助~

  • 在函数代码前加上:

     #pragma CODE_SECTION(f, ".TI.ramfunc")
     void f(void) { ... }

    在cmd文件里加上:
    .TI.ramfunc : {} > RAM

  • 唐工:
    “.TI.ramfunc” 这个指的就是L2吗?
    我一般是把重要用的比较多的变量定义到L2里面,然后打开cache。把程序段定义到L2里面还没试过。过,

    // 使能缓存 L1 及 L2
    config_cache();


    ......
    TXBUFF0: align=128 > L2
    TXBUFF1: align=128 > L2
    TXBUFF2: align=128 > L2
    RXBUFF0: align=128 > L2
    RXBUFF1: align=128 > L2
    RXBUFF2: align=128 > L2
    ......
  • yu tao3 说:
    “.TI.ramfunc” 这个指的就是L2吗?

    这是一个随便取的section名字.

    yu tao3 说:
    我一般是把重要用的比较多的变量定义到L2里面,然后打开cache。

    怎么把重要用的比较多的变量定义到L2? 

    打开cache跟分配内存又是什么关系?

  • 我只把L2平分成了2个部分,一个部分存取用的比较多的变量,另外作为cache用。
  • 感谢,但是我使用的是TI例程ex04_sharedregion,在LINUX下完成编译,但是在工程文件夹里面没有找到CMD文件啊?

  • 你随便搜一下吧,这个就是DSP的设置DSP的内存怎么使用的。你要按照你实际的分配写。或者在ccs下面新建一个工程,那个是自带一个cmd文件,在这个上面修改也可以。

    /****************************************************************************/
    /*                                                                          */
    /*              OMAPL138 及 DSP C6748 内存空间分配定义                      					*/
    /*                                                                          */
    /*              2017年05月16日                                              								*/
    /*                                                                          */
    /****************************************************************************/
    //-heap 0x00A00000   //堆大小10M
    //-stack 0x1000
    
    // ============================================================================
    //                         Specify the System Memory Map
    // ============================================================================
    MEMORY
    {
        L2:     o = 0x11800000        l = 0x00020000
        DDR2:   o = 0xC0000000        l = 0x08000000
    }
    
    // ============================================================================
    //                 Specify the Sections Allocation into Memory
    // ============================================================================
    SECTIONS
    {
        .cinit        >        DDR2               // Initialization Tables
        .pinit        >        DDR2               // Constructor Tables
        .init_array   >        DDR2               //
        .binit        >        DDR2               // Boot Tables
        .const        >        DDR2               // Constant Data
        .switch       >        DDR2               // Jump Tables
        .text         >        DDR2               // Executable Code
        .text:_c_int00: align=1024 > DDR2         // Entrypoint
        .args			>  DDR2
        .ppinfo			>  DDR2
        .ppdata			>  DDR2
        GROUP (NEARDP_DATA)                       // group near data
        {
           .neardata
           .rodata
           .bss                                   // note: removed fill = 0
        }             >        DDR2
        .far			>      DDR2               /* 远程全局及静态变量 */
        /*.far: fill = 0x0, load > DDR2  */       // Far Global & Static Variables
        .fardata      >        DDR2               // Far RW Data
        .stack        >        DDR2               // Software System Stack
        .sysmem       >        DDR2               // Dynamic Memory Allocation Area
        .cio          >        DDR2               // C I/O Buffer
        .vecs         >        DDR2               // Interrupt Vectors
    
        AECG4_CORE_PROG_SECT  :{ } >   L2
        tansmit: align=128 > L2
        RXIN: align=128 > DDR2
        TXIN: align=128 > DDR2
        RXOUT: align=128 > DDR2
        TXOUT: align=128 > DDR2
    }

  • 很有可能你操作(运算)输出的数据并没有给其他地方使用,优化的时候会认为你的操作是无用的操作,便帮你干掉了呃.
  • shuo wang 说:
    但是我使用的是TI例程ex04_sharedregion,在LINUX下完成编译,但是在工程文件夹里面没有找到CMD文件啊?

    这个例程应该是用了BIOS,用的是RTSC 配置文件分配的内存空间。

    #1,你前面的用GPIO来计算时间有个问题,没有把操作GPIO本身需要花的时间去掉。

    建议方法,连接拉高,拉低,拉高GPIO,它们之间的差值则是拉高,拉低GPIO操作要花的时间,然后在你前面的测试结果里将它减掉,才是真真的那个for循环花的时间。

     #2. 配置MARn寄存器,使能memory的Cache属性。

    #3. 编译优化选项加上-o2或者-o3.