gpt4 book ai didi

optimization - 在使用许多 SWIG 生成的模块时避免重复的 SWIG 样板

转载 作者:行者123 更新时间:2023-12-03 16:14:58 28 4
gpt4 key购买 nike

使用 SWIG 生成接口(interface)模块时,生成的 C/C++ 文件包含大量静态样板函数。因此,如果想通过在同一个应用程序中使用许多单独编译的小接口(interface)来模块化 SWIG 生成的接口(interface)的使用,那么由于这些重复的功能,最终会导致很多臃肿。

使用 gcc 的 -ffunction-sections选项,以及 GNU 链接器的 --icf=safe选项(-Wl,--icf=safe 给编译器),可以删除一些重复,但绝不是全部(我认为它不会合并任何有重定位的东西——这些函数中的许多都是这样做的)。

我的问题:我想知道是否有办法删除更多这种重复的样板,最好是不依赖于 GNU 特定的编译器/链接器选项。

特别是,是否有 SWIG 选项/标志/某些内容显示“不在每个输出文件中包含样板”?实际上有一个 SWIG 选项,-external-runtime这告诉它生成一个“仅样板”输出文件,但没有明显的方法来抑制每个正常输出文件中包含的副本。 [我认为这种事情在 SWIG 中实现起来应该相当简单,所以我很惊讶它似乎不存在......但我似乎找不到任何记录。]

这是一个小例子:

给定接口(interface)文件swg-oink.swg用于模块 swt_oink :

%module swt_oink
%{ extern int oinker (const char *x); %}
extern int oinker (const char *x);

...和类似的界面 swg-barf.swg对于 swt_barf :
%module swt_barf
%{ extern int barfer (const char *x); %}
extern int barfer (const char *x);

...和一个测试主文件, swt-main.cc :
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"

extern int luaopen_swt_oink (lua_State *);
extern int luaopen_swt_barf (lua_State *);
}

int main ()
{
lua_State *L = lua_open();
luaopen_swt_oink (L);
luaopen_swt_barf (L);
}

int oinker (const char *) { return 7; }
int barfer (const char *) { return 2; }

并像这样编译它们:
swig -lua -c++ swt-oink.swg
g++ -c -I/usr/include/lua5.1 swt-oink_wrap.cxx
swig -lua -c++ swt-barf.swg
g++ -c -I/usr/include/lua5.1 swt-barf_wrap.cxx
g++ -c -I/usr/include/lua5.1 swt-main.cc
g++ -o swt swt-main.o swt-oink_wrap.o swt-barf_wrap.o

那么每个xxx的大小 _wrap.o文件大约 16KB,其中 95% 是样板文件,最终可执行文件的大小大致是这些的总和,大约 39K。如果用 -ffunction-sections 编译每个接口(interface)文件,并链接到 -Wl,--icf=safe ,最终可执行文件的大小为 34KB,但显然仍有很多重复项(在可执行文件上使用 nm 可以看到多次定义的大量函数,并查看它们的源代码,很明显可以对它们中的大多数使用单一的全局定义)。

最佳答案

我相当确定 SWIG 没有这样做的选项。我现在在猜测,但我认为原因很可能是担心使用不同版本的 SWIG 构建的模块的可见性。想象以下场景:

两个库 X 和 Y 都使用 SWIG 为其代码提供接口(interface)。他们都选择让“SWIG 胶水”在不同的翻译单元中可见,以减少代码大小。如果 X 和 Y 都使用相同版本的 SWIG,这一切都会很好。如果 X 使用 SWIG 1.1 而 Y 使用 SWIG 1.3 会发生什么?两个模块都可以自己正常工作,但是取决于平台如何处理共享对象以及语言本身如何加载它们(RTLD_GLOBAL?)在同一 VM 中使用的两个模块的组合可能会发生一些非常糟糕的事情.

我怀疑代码重复的代价非常低——在 VM 和 native 代码之间交换的成本通常非常高,这可能会使略微减少的指令缓存命中相形见绌,尽管看到真正的基准测试可能会很有趣。从好的方面来说,这是用户无需担心的代码,因为它都是自动生成的,并且都正确地保留了为相应版本编写的接口(interface)。

关于optimization - 在使用许多 SWIG 生成的模块时避免重复的 SWIG 样板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8178479/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com