【问题标题】:millisecond-accurate benchmarking in C++?C++ 中毫秒级的基准测试?
【发布时间】:2011-04-17 09:31:59
【问题描述】:

我真的不想进行分析,因为我想对不同的简单函数进行许多不同的小型基准测试。对于我的一生,我无法找到一种方法来记录 C++ 中的毫秒数,顺便说一下,我正在使用 Linux。

您能否建议以毫秒为单位获取系统时钟的方法(如果我找不到简单的方法,我可能会以秒为单位……)以及它们包含在什么标题中?

【问题讨论】:

标签: c++ linux benchmarking clock gettimeofday


【解决方案1】:

使用sys/time.h头文件中的gettimeofday函数,我使用这个类:

#include <cstdlib>
#include <sys/time.h>

class Timer
{
    timeval timer[2];

  public:

    timeval start()
    {
        gettimeofday(&this->timer[0], NULL);
        return this->timer[0];
    }

    timeval stop()
    {
        gettimeofday(&this->timer[1], NULL);
        return this->timer[1];
    }

    int duration() const
    {
        int secs(this->timer[1].tv_sec - this->timer[0].tv_sec);
        int usecs(this->timer[1].tv_usec - this->timer[0].tv_usec);

        if(usecs < 0)
        {
            --secs;
            usecs += 1000000;
        }

        return static_cast<int>(secs * 1000 + usecs / 1000.0 + 0.5);
    }
};

例如:

#include <iostream>
#include <string>
#include <sstream>

int main()
{
    Timer tm;
    std::ostringstream ooo;
    std::string str;

    tm.start();
    for(int i = 0; i < 10000000; ++i)
    {
        ooo << "This is a string. ";
    }
    tm.stop();
    std::cout << "std::ostingstream -> " << tm.duration() << std::endl;

    tm.start();
    for(int i = 0; i < 10000000; ++i)
    {
        str += "This is a string. ";
    }
    tm.stop();
    std::cout << "std::string -> " << tm.duration() << std::endl;
}

【讨论】:

  • wok:四舍五入可能有助于在转换为 int 时提供帮助,因此 999 向下舍入为一而不是零。
  • @PC2st:那是我第一次完全“了解”代码的作用,这对我有很大帮助,我曾经在 PHP 中进行基准测试,但是测量算法是不准确的.非常感谢。
  • @wok:John 说了原因,+ 0.5 用于对结果进行四舍五入,但如果结果的符号为负,那么我们必须使用- 0.5 而不是+ 0.5
【解决方案2】:

如果您使用的是 x86 CPU,您可以使用 rdtsc 汇编指令http://en.wikipedia.org/wiki/Rdtsc 来获取执行两个(或更多)命令之间的 CPU 时钟数。 但: 1. 所有 rdtsc 命令都应该在同一个 CPU 内核上运行(如果你有多核 CPU)。 2. CPU 应以恒定时钟频率运行(应禁用 CPU 电源管理)。

迪玛

【讨论】:

  • 一个有趣的想法,谢谢。抱歉,我不能 +1,没有登录。
  • 有些 PC 实际上跨内核工作,有些则漂移数百毫秒。对于有缺陷的固件,在启动时旋转两个核心绑定线程以获得 { core1-clocks, core2-clocks, core1-clocks... },每个线程在看到另一个线程执行相同操作时立即写入其值。在我的 PC 上,将内核到内核的增量缩小到 ~400 ~3GHz 周期。然后获取每个时间戳,CPUID(1)/RDTSC/CPUID(2),如果两条 CPUID 指令报告不同的内核,则旋转。
猜你喜欢
  • 2011-04-18
  • 2017-11-07
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-29
  • 1970-01-01
  • 2014-09-16
相关资源
最近更新 更多