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.

[参考译文] AM5718:适用于 C66x DSP 的 OpenCL 分析支持/工具

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/566791/am5718-opencl-profiling-support-tools-for-c66x-dsp

器件型号:AM5718

您好!

我正在尝试找出 一种很好的方法来描述我在 DSP 上运行的程序(在 OpenCL 运行时)。 通常、在 ARM 或 x86 CPU 上进行开发时、我会说#include ,然后使用 struct timeval 和函数 gettimeofday 来设置时间戳,然后从整个代码的 tiem戳 中获取增量时间,以测量代码不同部分的运行时间(精度为或多或少的微秒)。 在为 DSP 编程时、是否有类似的东西可用?

我在不同的位置查找了可能暴露高分辨率计时器功能的 include 文件:

TI/ccsv6/tools/compiler/ti-cgt-C6000_8.1.0/include
tisdk/filesystem/tisdk-rootfs-image-am57xx-evm//usr/share/ti/OpenCL
tisdk/filesystem/tisdk-rootfs-image-am57xx-evm/usr/share/ti/CgT-C6x/include

等等 但我没有找到与 SYS/time.h API 类似的内容

我在 processors.wiki.ti.com/index.php/Category:Simulation 上开始研究 DSP 仿真器、但随后又研究了以下信息:

"CCSv6没有任何仿真器。 德州仪器不再提供仿真器、而是专注于提供低成本开发板。" (按 processors.wiki.ti.com/index.php/List_of_Simulator)

因此、仿真器路径看起来不是最佳路径。 到目前为止、我的研究表明 CCS 具有一些用于 DSP 的代码分析功能、但我想在调试环境之外进行运行时分析。 我想在尽可能真实的环境环境中(读取侵扰度最低)配置我的代码而不使用 JTAG 或其他调试支持、以便捕获 OpenCL 派单、计算器件处理和 IPC 开销的全部动态特性。

谢谢、

Weston

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

    已通知 DSP 专家。 他们将在这里作出回应。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你(们)好、Weston

    我的理解是、您尝试从 OpenCL 环境对 DSP 执行进行基准测试。  OpenCL 有一个很好的工具来实现这一点。

    查看 TI 设计 www.ti.com/.../TIDEP0046 、了解该设计如何使用事件对象(我称为事件实例 EV 和 EV2等)测量执行时间。  TI 设计是 C++、但在 C 语言中有等效项。事件对象的函数 getProfilingInfo 部分为用户提供了大量信息(任务何时发送到 DSP、    DSP 执行的时间等等)

    如需更多信息、请参阅 TI OpenCL 文档

    我是否回答了您的问题?  如果是、请关闭螺纹

    此致

    已运行

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

    您好、Ran、

    感谢您的回答。 我正在使用 OpenCL 事件对程序的总体执行时间进行基准测试、类似于 Monte-Carlo 仿真示例。 因此、我具有内核执行本身的粗调时序、以及 IPC 读/写缓冲区的精细时序。 但我还在 OpenCL 内核之外执行大量 C 库代码(使用 TI 扩展名:从 OpenCL C 代码调用标准 C 代码:downloads.ti.com/mctools/esd/docs/opencl/extensions/standard-c-code.html)。 我要分析的是这个库代码。

    谢谢、

    Weston

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

    1.您仍然可以从 OpenCL 派送 DSP 库函数并使用 OpenCL 测量时间
    2.每个库函数都有单元测试。 您可以使用 CCS 来测量周期。 提示-使用完整的符号调试编译测试代码、并使用发布库函数来测量时间。

    顺便说一下、您对什么功能感兴趣?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Ran、

    我要调用的库是自定义库。 DSP 执行的任务是图像处理操作。 我将图像排队到 CL 写入缓冲区中、并将一些参数控制图像处理到另一个写入缓冲区中、然后在 DSP 上执行图像处理任务(使用库代码)、然后通过读取缓冲区返回处理结果。 我还想在返回读取缓冲区中为图像处理序列中的各个步骤执行时间戳。

    Weston

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

    这是我的建议。 您可以在 DSP 内核上使用 TSCl TSCH 寄存器。 在执行开始时读取这两个值、并将这些值存储在全局变量中、在执行结束前再次读取它们、然后再次存储在(不同的)全局变量中。 然后打印这些值并计算周期数

    下面是一个伪代码、它使用 printf 执行类似的操作、而不是将数据存储在全局变量中

    长漫射时间,漫射时间2;

    无符号长整型 t1、t2、t1h、t2h;


    TSCL = 0;//这是启用寄存器时钟的必做操作
    T1 = TSCL;
    t1h = TSCH;
    T2 = TSCL;
    T2H = TSCH;
    diffTime =(long long)(T2H - t1H))* 0x0100000000 +(long long)(T2-T1);//这是为了确定开销
    printf ("开销时间为%d \n",diffTime);

    T1 = TSCL;
    t1h = TSCH;

    executeSignalProcessingCode();

    T2 = TSCL;
    T2H = TSCH;
    diffTime2 =((long long)(T2H - t1H))* 0x0100000000 +(long long)(T2-T1);
    printf (“t1 %d t1h %d t2 %d t2h %d”、t1、t1h、t2、t2h);
    printf ("时间通过(以毫秒为单位)%e \n "、
    (float)(((float)(diffTime2 - diffTime))/(1000000000.0)));
    现在、不是 printf 存储这些值、而是稍后读取它们

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

    RAN、

    非常感谢你的帮助。  我应该接近具有上述伪代码的解决方案。 使用以下文档:TMS320C6000优化编译器 v8.1.x 用户指南、部分: 7.5.3 _cregister 关键字、和文档:TMS320C66x DSP CPU 和指令集参考指南、部分:2.9.13时间戳计数器寄存器(TSCL 和 TSCH)、 我已经执行了:

    #include "c6x.h"
    
    //本地 t0用于处理开始时间。
    unsigned long long int _StartTime = 0;
    
    //由__cregister 关键字提供的控制寄存器访问,请参阅:c6x.h
    。extern __cregister volatile unsigned int TSCL;
    extern __cregister volatile unsigned int TSCH;
    
    void enable_cpu_clock_counter (void){
    TSCL = 0;
    }
    
    unsigned long int get_timestamp (void)
    {
    返回((unsigned long long int) TSCH << 32)+(unsigned long long int) TSCL;
    }
    
    void set_timestamp (unsigned long int timestamp)
    {
    _StartTime =时间戳;
    }
    
    unsigned int UpTime (void)
    {
    返回(unsigned int)(get_timestamp()-_StartTime);
    } 

    为 ENABLE_CPU_CLOCK _COUNTER 生成以下汇编代码:

    ;********
    ;*函数名称:enable_cpu_clock_counter() *
    ;* *
    ;* Regs Modified :B4 使用*
    ;* Regs :B3,B4 *
    ;*本地帧大小:0 args + 0 Auto + 0 Save = 0字节 *
    
    _z24enable_cpu_clock_counterv:
    ;**---------------
    *; 专用 CPU 周期:8.
    零.L2 B4 ;[B_L66]|25|
    MVC S2. B4、TSCL ;[B_Sb66]|25|
    RETNOP B3,5. ;[]|26|
    ;分支发生{B3} ;[]|26|
    .sect".text"
    .clink
    .global_Z13set_timestampy 

    根据文档、这看起来是启动 CPU 时钟计数器的正确方法。 我只是返回 Δ 时钟节拍、而不是将时钟节拍转换为实际时间值。  

    这似乎起作用。

    谢谢、

    Weston