Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 大型C+的性能惩罚+;dll';使用自动生成的C代码_C++_C_Performance_Dll - Fatal编程技术网

C++ 大型C+的性能惩罚+;dll';使用自动生成的C代码

C++ 大型C+的性能惩罚+;dll';使用自动生成的C代码,c++,c,performance,dll,C++,C,Performance,Dll,我正在开发一款软件,需要调用一系列优化解决方案。每个解算器都是一段自动生成的C代码,包含数千行代码。我使用了其中的200个解算器,不同的只是要解决的优化问题的大小 总而言之,这些自动生成的求解器大约是180MB的C代码,在VisualStudio 2008中,使用外部“C”{/* 200求解器*/} < /C>语法>,将其编译成C++。编译所有这些都非常慢(使用“最大速度/O2”优化标志,大约需要8小时)。出于这个原因,我认为将解算器编译成一个单独的DLL是个好主意,然后我可以从一个单独的软件中

我正在开发一款软件,需要调用一系列优化解决方案。每个解算器都是一段自动生成的C代码,包含数千行代码。我使用了其中的200个解算器,不同的只是要解决的优化问题的大小

总而言之,这些自动生成的求解器大约是180MB的C代码,在VisualStudio 2008中,使用<代码>外部“C”{/* 200求解器*/} < /C>语法>,将其编译成C++。编译所有这些都非常慢(使用“最大速度/O2”优化标志,大约需要8小时)。出于这个原因,我认为将解算器编译成一个单独的DLL是个好主意,然后我可以从一个单独的软件中调用它(这将有一个合理的编译时间,并允许我从更高级别的代码中抽象出所有这些外部“C”内容)。编译后的DLL大约为37MB


问题是,当使用DLL执行其中一个解算器时,执行大约需要30毫秒。如果我只将一个解算器编译成DLL,并从同一个程序调用它,执行速度大约快100倍(请确保测量并平均多次调用优化器的时间,因为在第一次调用之前,可能会有很大的设置开销


然后还要检查200分支条件语句(您的开关)是什么正在对您的性能造成影响!请尝试取消用于测试的开关,在测试项目中只调用一个解算器,但在DLL中链接所有解算器。您是否仍然看到性能缓慢?

我认为您生成代码的原因是为了更好的运行时性能,以及更好的正确性。 我也这么做

我建议您尝试找出运行时性能问题是什么

如果您看到100:1的性能差异,这意味着每次您中断它并查看程序的状态时,您都有99%的机会看到问题所在

就构建时间而言,确保模块化是有意义的。
所有这些都不会对运行时产生太大影响,除非这意味着您正在进行疯狂的I/O。

我不知道您的代码是否内联到示例中的每个case部分中。如果您的函数是内联函数,并且您将所有函数都放在一个函数中,那么运行速度会慢得多,因为代码被放在虚拟内存中,这将需要当代码被执行时,CPU会有很大的跳跃。如果它不是全部内联的,那么这些建议可能会有所帮助

您的解决方案可能会通过以下方式得到改进

(A) 1) 将项目划分为200个独立的DLL。然后使用.bat文件或类似文件构建。 2) 在每个dll中创建名为“MyEntryPoint”的导出函数,然后根据需要使用动态链接加载库。这将相当于一个繁忙的音乐程序,加载了许多小的dll插件。使用GetProcAddress获取指向入口点的函数指针

或者

B) 将每个解决方案构建为一个单独的.lib文件。然后,每个解决方案都会非常快速地编译,然后您可以将它们链接到一起。构建一个指向所有函数的函数指针数组,并通过查找来调用它

结果=哪一步

将所有库合并成一个大库不需要八个小时。如果需要那么长时间,那么你是在做一些非常错误的事情

而且


尝试将代码放入不同的实际.cpp文件中。如果它们都在不同的单元中,那么这个特定的编译器可能会做得更好。。。然后,一旦每个单元被编译,如果您不做任何更改,它将保持编译状态。

您在哪个平台上观察到这一点?在32位体系结构的Linux上,
。所以
文件需要
-fPIC
,它占用一个寄存器,所以代码运行速度可能会慢5%(因为编译器溢出更多)。Post提到了Visual Studio和DLL,它们是Windows。@Basile,themel:是的,都是在Windows上,用VS2008编译的。但如果是32位的Windows,这可能会有问题(可能还为编译DLL代码保留了额外的寄存器)或Windows 64位。这可能与Windows系统上的ABI约定有关(32位和64位系统的ABI约定不同)@Basile:都是32位的。Edit:抱歉,说清楚一点:我正在编译Win32,但我在64位Windows 7上运行。我平均进行了100多次调用,但第一次调用似乎没有明显的区别。我将尝试链接所有解算器,但删除开关——不幸的是,此测试将涉及为ful编译/代码生成我有个计划,所以需要一天的时间。
extern "C"{
#include "../Generated/include/optim_001.h"
#include "../Generated/include/optim_002.h"
/*etc.*/
#include "../Generated/include/optim_200.h"
}

namespace InterceptionTrajectorySolver
{

__declspec(dllexport) InterceptionTrajectoryExitFlag SolveIntercept(unsigned numSteps, InputParams params, double* optimSoln, OutputInfo* infoOut)
{
  int exitFlag;

  switch(numSteps)
  {
  case   1:
    exitFlag = optim_001_solve((optim_001_params*) &params, (optim_001_output*) optimSoln, (optim_001_info*) &infoOut);
    break;
  case   2:
    exitFlag = optim_002_solve((optim_002_params*) &params, (optim_002_output*) optimSoln, (optim_002_info*) &infoOut);
    break;
  /*
    ...
    etc.
    ...
  */
  case   200:
    exitFlag = optim_200_solve((optim_200_params*) &params, (optim_200_output*) optimSoln, (optim_200_info*) &infoOut);
    break;
  }

  return exitFlag;
};

};