你如何基准一个函数的性能 [英] how would you benchmark the performance of a function

查看:116
本文介绍了你如何基准一个函数的性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能是一个更高级的问题。如果你有两个函数返回一个值

$ p $ int F(int input1,int input2)
{
int输出;
//将值分配给输出的一些算法//
返回输出;


int D(int input1,int input2)
{
int output;
//将值分配给输出的另一个算法//
返回输出;

$ / code>

满足条件F(a,b)== D (a,b)(两者都会为相同的输入返回相同的值)。

如果您想以自己的表现为基​​准,它?
更准确地说,您将如何分离执行 F(a,b) D(a,b)所需的时间,使其 not 反映基准设置中其他二级操作所花费的时间

解决方案

最好的开源解决方案之一是谷歌基准
您必须围绕您想要进行基准测试的代码创建简单的包装,并与基准库进行静态或动态链接。在您的代码附近编译这样的微基准通常很有用。有关灵感,请参阅精彩的演示文稿

  static void BM_F(benchmark :: State& state){
const auto input1 = state.range_x();
const auto input2 = state.range_y(); (state.keeprunning())F(input1,input2);

while


static void BM_D(benchmark :: State& state){
const auto input1 = state.range_x();
const auto input2 = state.range_y();

while(state.keeprunning())D(input1,input2);
}

基准(BM_F)
- > ArgPair(1,10)
- > ArgPair(10,100)
- > ArgPair(100,1000);

基准(BM_D)
- > ArgPair(1,10)
- > ArgPair(10,100)
- > ArgPair(100,1000 );

如果您想测量原始CPU周期,那么您唯一的选择是使用直接的CPU指令。对于x86,您可以使用时间戳计数器。但是你应该知道,这种测量不会抵制任何由OS执行的上下文切换或者在CPU上跳转。在这种情况下,您唯一的选择是使用算法执行单一流程,在进入测试功能之前记住CPU的ID和TSC值,并在测试功能之后检查CPU的ID。然后计算TSC值之间的差异。您可能还会为您的进程设置CPU关联,以将进程绑定到特定的CPU。



另一种特定于Linux功能的基准测试方法是使用 perf工具



但是无论如何,任何措施会为结果添加一些错误级别。


here's perhaps a more advanced question. if you have two functions that return a value

int F(int input1, int input2)
{
    int output;
    //some algorithm that assigns value to output//
    return output;
}

int D(int input1, int input2)
{
    int output;
    //another algorithm that assigns value to output//
    return output;
}

With the condition that F(a,b) == D(a,b) (both return the same value for the same inputs).

If you'd like to benchmark their performance, how would you do it? More precisely, how would you isolate the time it takes to perform F(a,b) or D(a,b) such that it does not reflect the time it takes for the other secondary operations in the benchmark setup?

解决方案

One of the best available opensource solutions is google benchmark . You have to create simple wrappers around code you want to benchmark and link either statically or dynamically with the benchmark lib. It is often useful to have such micro benchmarks compiled near with your code. For inspiration see awesome presentation.

static void BM_F(benchmark::State& state) {
  const auto input1 = state.range_x();
  const auto input2 = state.range_y();

  while (state.KeepRunning()) F(input1, input2);
}

static void BM_D(benchmark::State& state) {
  const auto input1 = state.range_x();
  const auto input2 = state.range_y();

  while (state.KeepRunning()) D(input1, input2);
}

BENCHMARK(BM_F)
    ->ArgPair(1, 10)
    ->ArgPair(10, 100)
    ->ArgPair(100, 1000);

BENCHMARK(BM_D)
    ->ArgPair(1, 10)
    ->ArgPair(10, 100)
    ->ArgPair(100, 1000);

If you want to measure raw CPU cycles, then your only choice is to use direct CPU instructions. For x86 you can use Time Stamp Counter. But you should be aware, that such measuring will not resist any context switches performed by OS or jumping on CPUs. Your only choice in such situation will be to use algo with single flow of execution, remember ID of CPU and TSC value before enter to test function, and check ID of CPU after test function. Then calculating difference between TSC values. You may also setup CPU affinity for your process to stick process to specific CPU.

Another Linux specific possible way to benchmark functions is to use perf tool.

But in any way, any measure will add some error level to the result.

这篇关于你如何基准一个函数的性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆