C++ 隐藏符号会增加重定位时间

Posted

技术标签:

【中文标题】C++ 隐藏符号会增加重定位时间【英文标题】:C++ Hiding Symbols increases relocation time 【发布时间】:2016-01-10 02:23:34 【问题描述】:

我正在尝试优化具有 200 多个依赖项的库的加载时间。我尝试使用可见性属性隐藏符号,这使我将导出的符号数量减少了 30%。

查看elf直方图,优化后bucket数量保持不变,但查找成功和不成功的次数减少了很多。布隆过滤器大小从 8kb 减少到 4kb,但设置的位数从 19% 增加到 24%。

尽管加载时间增加了,我认为这是由于布隆过滤器中设置的位数高于以前。

查看依赖项,我可以看到大约有 400.000 个符号在重定位时被查看到我的库中但没有成功。布隆过滤器用于过滤其中的大部分,但由于位集数量较多,误报的数量从 3.6% 增加到 5.76%(我在互联网上找到了这个公式:误报=bitsets%^2)

在优化之前做一些数学运算,我不得不在我的库中搜索 14.440 误报,在优化之后,这个数字上升到 23.040。即使不成功的查找从 1.7 减少到 1.1,比较次数仍然比以前更高。

我还使用 calgrind 对其进行了测试,证实优化降低了库的性能。库本身比以前快了大约 2%,但重定位时间增加了大约 1%(在 ld strcmp 调用中从 3575000 上升到 3617000)。

我还尝试使用导出映射进一步减少导出符号的数量,这帮助我将导出符号的数量减少了 50%。但情况更糟。桶的数量是一半,但不成功的查找提高到 1.4,布隆过滤器大小到 2kb,位集为 29%,误报率为 8.4%。

隐藏符号如何增加重定位时进行的比较次数?如果布隆过滤器对结果的影响如此之大,为什么链接器更喜欢减小其大小而不是减少误报的百分比?有没有可以帮助我的链接器选项?

提前谢谢你

【问题讨论】:

布隆过滤器大小从 8kb 减少到 4kb,但设置的位数从 19% 增加到 24%....这是什么意思??布隆过滤器中的桶下降了吗? 布隆过滤器是一个位集,链接器使用散列函数为库导出的每个符号设置 2 位。它用于在重定位(加载)时了解符号是否在库中定义(过滤器是概率性的:可能存在误报匹配,但不会出现误报)。过滤器越大,重定位时使用的内存越大,但误报的数量越小。如果您有加载时间而不是内存的限制,那么在重定位过程中使用更大的布隆过滤器和更小的误报率会更好。 【参考方案1】:

前段时间我正在为媒体播放器应用寻找类似的东西。

使用direct binding 确实有助于减少符号解析时间。

不确定隐藏符号对布隆过滤器的影响。

有什么链接器选项可以帮助我吗?

据我所知,没有办法调整符号查找中使用的布隆过滤器。

那里有一些不错的文章,但没有一篇强调调整布隆过滤器。

bloom filter elf

cost of elf symbol

【讨论】:

以上是关于C++ 隐藏符号会增加重定位时间的主要内容,如果未能解决你的问题,请参考以下文章

计算机系统篇之链接:静态链接(下)——重定位

计算机系统篇之链接:静态链接(下)——重定位

为啥需要重定位同一文件中的全局符号?

ELF 动态链接 - so 的 重定位表

图片+代码:GCC 链接过程中的重定位过程分析.md

图片+代码:GCC 链接过程中的重定位过程分析.md