如何将呼叫保持在线,但要避免编译器警告

How to keep calls inlined but avoid compiler warnings?

本文关键字:警告 编译器 在线 呼叫      更新时间:2023-10-16

我有一个类,该类在我的软件中的所有代码中广泛使用。该类是具有某些几何函数的点抽象,并且通过坐标类型(例如长或double)进行模板。如果在动态库之间传递这一点,我会得到编译器警告 c4252:类"点"需要让'ethoterclass''''ofers'emotclass'的客户使用dll-interface 具有相同的编译设置。

由于我们的策略根本没有警告,我们决定标记两个广泛使用的模板专业dll,例如这样(在带有模板的标题中):

 template class __declspec(dllexport) Point<long>;
 template class __declspec(dllexport) Point<double>;

,但是现在编译器用常见的函数调用代替了所有嵌入式,并且由于大量使用了该类,我们的代码变慢了得多。

问题是:是否有任何方法可以在每个库中保留呼叫,但仍在使用DLL之间的数据并避免警告?

我们使用Microsoft VC 2012编译器。

在我的经验中,如果速度是一个问题,我通过使用静态链接的代码/header仅inlinefastcall代码而不是DLL s获得了更好的性能,但是您的描述是确切的原因,回想起来,我认为可能有某种方法可以实现您的意思,尽管我怀疑基准测试仍会显示静态链接的代码以保持更快。

我正在考虑强迫DLL S在加载时间居住(并且确实可以按照文章在此处执行此操作),以便可以与内线/静态链接代码相似的性能成就了。

这似乎一开始就起作用,但是,如果在任何时候分类了DLL的内存,它将变得像动态访问DLL代码一样慢。

直到我研究了链接到 DLL s的进一步方法,我个人会个人推荐 inline fastcall 代码,如果这是一种选项,尽管这会导致可执行文件更大,并且可能会影响您的发布内存足迹是一个问题。

作为您上面提到的两行的快速修复,您可以尝试更改:

template class __declspec(dllexport) Point<long>;
template class __declspec(dllexport) Point<double>;

to

extern template class __declspec(dllexport) Point<long>;
extern template class __declspec(dllexport) Point<double>;

应该希望删除您所遇到的问题。(有关此操作的更多信息,此处可在此页面上使用,用于导出包含STL类的STL类或似乎是同一问题的对象的实例)。

然而,内部(一个汇编阶段"优化")天生坐着的原理是从DLL导出/导入/导入的:前者通过将所有内容组合在一起,以优化速度,后者对内存足迹/模块化优化,以通过将代码分为不同的较小捆绑包,可以在需要时调用。

注意:

  1. fastcall将一个或多个参数放入寄存器中,从而减少执行所需的内存调用数量。

    • 对于MSOFT和GCC,当您只有2个参数时,您会获得最明显的速度好处。
    • Borland编译器将允许使用多达3个寄存器/参数
  2. 还请注意,内联关键字不能保证代码将被绑架,这只是对编译器,但是其他优化标志可以将其删除或直列您未标记为内联的其他部分。

希望这会有所帮助,但是与往常一样,如果您需要更多信息/帮助,请告诉我。:)