【问题标题】:How to check time performances in a C++ program on Zedboard如何在 Zedboard 上检查 C++ 程序的时间性能
【发布时间】:2017-11-10 00:49:12
【问题描述】:

我在 Zedboard 上实现了 C++ 代码。它编译和运行完美,但现在我想检查性能以优化一些功能。 我在这里(Testing the performance of a C++ app)和这里(Timer function to provide time in nano seconds using C++)检查了一些线程,但我真的不明白如何应用它 mon code ...

说清楚:我不擅长 C++,我从未真正正式学习过这门语言,只是在特定的库中使用过几次。我什至不是我正在使用的代码的作者(教授给我的)。

我的目标是在 Zedboard 上执行程序时检查每个函数和全局花费的时间。该代码位于 SD 卡上的 Linux 映像上,开发板在此映像上启动。它正在将 opencv 库用于图像处理应用程序。我使用 g++ 4.6.3 作为编译器。

提前感谢您的回答!

【问题讨论】:

  • 你需要定义一个定时器,然后获取你执行函数前后的时间。不同之处在于您经过的功能时间。
  • Valentin,你还在 Zedboard 的 Zynq SoC 的 ARM 端(PS)吗?它应该像 ARMv7 时代的任何其他 ARM Cortex-A9 或其他 ARM Cortex-A 一样工作。请告诉我们您的编译器是什么及其版本(您用于交叉编译代码的赛灵思工具版本;您是如何编译代码的)。
  • @osgx 我在安装在 SD 卡上的 Linaro Ubuntu 上进行了 Zedboard 启动,所以我想我正在研究 ARM 而不是 FPGA 部分。我在我的 Makefile 中使用 g++ -4.6 在终端中编译。

标签: c++ time fpga xilinx


【解决方案1】:

您可以使用<chrono> 标头创建一个简单的计时器类。像这样的:

class Timer
{
public:
    using clock = std::chrono::steady_clock;

    void clear() { start(); tse = tsb; }
    void start() { tsb = clock::now(); }
    void stop()  { tse = clock::now(); }

    auto nsecs() const
    {
        using namespace std::chrono;
        return duration_cast<nanoseconds>(tse - tsb).count();
    }

    double usecs() const { return double(nsecs()) / 1000.0; }
    double msecs() const { return double(nsecs()) / 1000000.0; }
    double  secs() const { return double(nsecs()) / 1000000000.0; }

    friend std::ostream& operator<<(std::ostream& o, Timer const& timer)
    {
        return o << timer.secs();
    }

private:
    clock::time_point tsb;
    clock::time_point tse;
};

你可以像这样简单地使用它:

Timer timer;

timer.start();

// do some stuff
std::this_thread::sleep_for(std::chrono::milliseconds(600));

timer.stop();

std::cout << timer << " seconds" << '\n';

编辑:POSIX 系统上,如果&lt;chrono&gt; 不可用,您可以使用clock_gettime()

class Timer
{
public:
    void clear() { start(); tse = tsb; }
    void start() { clock_gettime(CLOCK_MONOTONIC, &tsb); }
    void stop() { clock_gettime(CLOCK_MONOTONIC, &tse); }

    long nsecs() const
    {
        long b = (tsb.tv_sec * 1000000000) + tsb.tv_nsec;
        long e = (tse.tv_sec * 1000000000) + tse.tv_nsec;
        return e - b;
    }

    double usecs() const { return double(nsecs()) / 1000.0; }
    double msecs() const { return double(nsecs()) / 1000000.0; }
    double  secs() const { return double(nsecs()) / 1000000000.0; }

    friend std::ostream& operator<<(std::ostream& o, Timer const& timer)
    {
        return o << timer.secs();
    }

private:
    timespec tsb;
    timespec tse;
};

【讨论】:

  • 谢谢你的回答,我会试试这个并发布结果。我想我必须在某个地方下载这个 标头才能工作?
  • @ValentinDubois No &lt;chrono&gt; 是标准 C++ 的一部分。
  • 不幸的是 标头未包含在我的版本中。我正在考虑使用 中的 clock_gettime()。
  • @ValentinDubois 当然,我也将它与 CLOCK_MONOTONIC 一起使用。
  • @ValentinDubois 我使用clock_gettime()在我的答案中添加了另一个示例。
【解决方案2】:

我找到了一个不满意的解决方案,但我认为如果它可以提供任何帮助,我仍然可以发布它。

我使用了&lt;time.h&gt; 中定义的gettimeofday() 函数。它使用起来非常简单,但有缺陷,我稍后会解释:

timeval t1, t2;
gettimeofday(&t1, NULL);
/* some function */
gettimeofday(&t2, NULL);
double time;
time = (t2.tv_sec - t1.tv_sec)*1000.0 + (t2.tv_usec - t1.tv_usec)/1000.0; 
cout << time << "ms" << "\n";

这样我以毫秒为单位测量时间并将其显示在屏幕上。但是gettimeofday 不是基于计算机时钟,而是基于实际时间。需要明确的是,两次调用之间经过的时间确实包含我的功能,但也包含在 Ubuntu 后台运行的所有进程。换句话说,这并没有给出我的函数执行所花费的精确时间,而是一个略高的值。

编辑:我再次找到了另一个解决方案,使用来自&lt;time.h&gt;clock() 函数,与我使用前一种方法得到的结果相比,结果似乎是正确的。不幸的是,精度不够,因为它以秒为单位给出了一个只有 3 位数字的数字。

【讨论】:

  • 在 Unix/Linux/POSIX 世界中也有 CPU 时间计时器(不是 "wall time"gettimeofday,或挂在房间墙上的时钟),由内核测量并报告为几个系统调用,如 getrusage 与 RUSAGE_SELF 和 ru_utime 字段。但这个时钟通常以 1 ms 或 10 ms 之类的大步长测量,不能用于测量 sub-ms 函数时序。
  • @osgx 感谢您的回答!你能不能给我一个简单的例子来说明我应该如何使用它?
  • Valentin,就像在 stackoverflow.com/questions/10509660/ 但使用 ru_utime。这也将为您提供低分辨率结果,点后 2 或 3 位(10 ms - 1 ms)。使用较长的程序部分进行测量,或使用 gettimeofday 并进行多次测量。当您的程序没有外部 I/O 或等待系统调用时,gettimeofday 将在大多数情况下返回正确且精确的值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-23
  • 1970-01-01
相关资源
最近更新 更多