c++ - 由于从未运行的函数调用,程序花费的时间比应有的时间长很多

标签 c++ boost include runtime boost-ublas

我目前正在运行用 C++ 编写的贝叶斯优化。我使用 Ruben Martinez-Cantin (http://rmcantin.bitbucket.org/html/) 的工具箱 Bayesopt。我正在做关于贝叶​​斯优化的论文 ( https://en.wikipedia.org/wiki/Bayesian_optimization )。

我之前曾试验过这个工具箱,本周我注意到代码运行速度比我内存中的要慢得多。值得一提的是,我确实编写了一些适用于此工具箱的代码。

我决定尝试了解为什么会发生这种情况,并且我确实看到代码运行速度比应有的慢得多。

为了了解这是我的代码的错误还是其他原因,我尝试了一个不使用我的任何代码的示例。

考虑以下示例:

#include <iostream>
#include <bayesopt.hpp>


class ExampleMichalewicz: public bayesopt::ContinuousModel
{
public:
  ExampleMichalewicz(bopt_params par);

  double evaluateSample(const vectord& x);
  bool checkReachability(const vectord &query) {return true;};

  void printOptimal();

private:
  double mExp;
};


ExampleMichalewicz::ExampleMichalewicz(bopt_params par):
  ContinuousModel(10,par) 
{
  mExp = 10;
}

double ExampleMichalewicz::evaluateSample(const vectord& x)
{
  size_t dim = x.size();
  double sum = 0.0;

  for(size_t i = 0; i<dim; ++i)
    {
      double frac = x(i)*x(i)*(i+1);
      frac /= M_PI;
      sum += std::sin(x(i)) * std::pow(std::sin(frac),2*mExp);
    }
  return -sum;
}

void ExampleMichalewicz::printOptimal()
{
  std::cout << "Solutions: " << std::endl;
  std::cout << "f(x)=-1.8013 (n=2)"<< std::endl;
  std::cout << "f(x)=-4.687658 (n=5)"<< std::endl;
  std::cout << "f(x)=-9.66015 (n=10);" << std::endl;
}

int main(int nargs, char *args[])
{
  bopt_params par = initialize_parameters_to_default();
  par.n_iterations = 20;
  par.n_init_samples = 30;
  par.random_seed = 0;
  par.verbose_level = 1;
  par.noise = 1e-10;
  par.kernel.name        = "kMaternARD5";
  par.crit_name          = "cBEI";
  par.crit_params[0] =   1;
  par.crit_params[1] =   0.1;
  par.n_crit_params  =   2;
  par.epsilon        =   0.0;
  par.force_jump     =   0.000;
  par.verbose_level  =   1;
  par.n_iter_relearn     =     1; // Number of samples before relearn kernel
  par.init_method        =     1; // Sampling method for initial set 1-LHS, 2-Sobol (if available),
  par.l_type             = L_MCMC; // Type of learning for the kernel params


  ExampleMichalewicz michalewicz(par);
  vectord result(10);

  michalewicz.optimize(result);
  std::cout << "Result: " << result << "->" 
      << michalewicz.evaluateSample(result) << std::endl;
  michalewicz.printOptimal();

  return 0;
}

如果我单独编译这个例子,运行时间大约是 23 秒。

用这个cmake文件

PROJECT ( myDemo )

ADD_EXECUTABLE(myDemo ./main.cpp)

find_package( Boost REQUIRED )
if(Boost_FOUND)
   include_directories(${Boost_INCLUDE_DIRS})
else(Boost_FOUND)
   find_library(Boost boost PATHS /opt/local/lib)
   include_directories(${Boost_LIBRARY_PATH})
endif()

include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories("../bayesopt/include")
include_directories("../bayesopt/utils")

set(CMAKE_CXX_FLAGS " -Wall -std=c++11 -lpthread -Wno-unused-local-typedefs -DNDEBUG -DBOOST_UBLAS_NDEBUG")

target_link_libraries(myDemo libbayesopt.a libnlopt.a)

现在考虑相同的主要示例,但我将三个附加文件添加到我的 cmake 项目中(不将它们包含在 main.cpp 中)。这三个文件是我所有代码的子部分。

PROJECT ( myDemo )

ADD_EXECUTABLE(myDemo ./iCubSimulator.cpp ./src/DatasetDist.cpp ./src/MeanModelDist.cpp ./src/TGPNode.cpp)

find_package( Boost REQUIRED )
if(Boost_FOUND)
   include_directories(${Boost_INCLUDE_DIRS})
else(Boost_FOUND)
   find_library(Boost boost PATHS /opt/local/lib)
   include_directories(${Boost_LIBRARY_PATH})
endif()

include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories("../bayesopt/include")
include_directories("../bayesopt/utils")

set(CMAKE_CXX_FLAGS " -Wall -std=c++11 -lpthread -Wno-unused-local-typedefs -DNDEBUG -DBOOST_UBLAS_NDEBUG")

target_link_libraries(myDemo libbayesopt.a libnlopt.a)

这一次,运行时间约为 3 分钟。这对我的工作至关重要,因为如果我增加 par.n_iterations,它往往会变得更糟。

我进一步得出结论,如果我在 TGPNode.cpp 中注释一行

utils::cholesky_decompose(K,L); (NOTICE THAT THIS LINE IS NEVER CALLED).

我得到 23 秒。此函数属于文件:ublas_cholesky.hpp,来自 bayesopt 工具箱。

同样重要的是要注意工具箱代码中也调用了相同的函数。此行没有注释,它在 michalewicz.optimize(result); 期间运行。

有没有人知道为什么会这样?如果有人对这个主题有一些了解,那将是一个很大的帮助。

非常感谢。

您好,何塞·诺盖拉

最佳答案

它不会返回。

它将无限递归(导致堆栈溢出)。

代码如下:

bopt_params initialize_parameters_to_default(void)
{
  bayesopt::Parameters par;
  return par.generate_bopt_params();

generate_bopt_params:

bopt_params Parameters::generate_bopt_params(){
    bopt_params c_params = initialize_parameters_to_default();

看起来有人试图在没有实际测试的情况下删除代码重复。完全没有。您可以恢复第一个函数的注释掉的主体

关于c++ - 由于从未运行的函数调用,程序花费的时间比应有的时间长很多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33549982/

相关文章:

c++ - std::vector 的奇怪行为

c++ - 在 C++ 函数声明中引用成员变量?

c++ - std::list 的 const_iterator 与迭代器

c++ - 如何将 boost::any_cast 转换为 std::string

c++ - 如何使用来自boost的模板相关信号成员实现模板类?

PHP include() before doctype,导致空白

c++ - 将一系列 typedef 转换为 char 数组

c++ - 插入以 boost 无序 map

c++ - Xcode 找不到#Include<> header

c# - Entity Framework 4.1 Code First - 使用 LinqKit PredicateBuilder 时忽略包含