LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2804|回复: 35

HASHSTYLE HOWTO 大致翻译过了

[复制链接]
发表于 2007-3-21 00:24:24 | 显示全部楼层 |阅读模式
大多数程序都需要用到共享库,这会导致较长的读取时间,比如运行时每一个库都需要被读取来解析符号。对多数小程序来说这没什么,但是对于用C++写的程序来说链接库太多了,时间加起来也就很长。
一个解决办法是prelining,这种办法预先进行链接,静态绑定可执行程序。这样会稍微增加一点可执行程序的的大小,但是程序启动时会获得一些戏剧性的加速。预链接的缺点是每当库改变时就需要重新链接,而且不能动态的读取库文件。所以对那些需要动态读取库文件的程序来说prelinking没有效果,比如OpenOffice。
下一种开发中的办法产生于对binutils和glibc的改进中,这种办法被称作直接链接,Bdirect。Bdirect不像prelinking那么有效,但是它可以很好的动态读取库文件,并且不需要任何用户进行的预链接步骤。

关于hashstyle

hashstyle很快成为了下一种选择,上流开发中的版本已经整合了这个补丁,这个改进就是新的 DT_GNU_HASH 或 .gnu.hash,现在被亲切的称为Hashstyle。新的.gnu.hash大约比老的sysv .hash快50%。
hashstyle还可以与prelinking共存(假设你有最新的elfutils 和 prelink),并且支持ELF标准,不像 -Bdirect,这也是 -Bdirect没被整合到upstream(不晓得怎么翻译=_=)的原因。

这个wiki详细叙述了如何迁移到新的hashstyles环境。在你开始动手尝试之前,请先仔细阅读并重复阅读每一部分。

协议
Gentoo Linux组织并不支持使用hashstyles补丁。如果要执行本文以下的步骤,你要同意对自己的行为负责。本文作者和投稿人对本文并不负任何责任,也不保证能提供任何帮助,但是会提供基本的可供你执行的步骤,不过没有更进一步的帮助。 (In the case your system is no longer usable - system is equal to the gentoo installation, not your computer.)

第一次安装hashstyle
现在需要把“hashstyle”添加 到/etc/make.con中的USE变量里。这里我假设你知道如何去做,你正在用一个实验补丁,所以你一定知道怎么做。
现在需要unmask实验中的binutils。对 gcc 4.x来说需要至少为2.17.50.0.3的版本,gcc 3.4.的话则需要 2.17.50.0.4
  1. /etc/portage/package.keywords
  2. sys-devel/binutils -*
复制代码

如果你需要用prelink,那还要unmask最新版本。如果你用的是不稳定版那这步可以跳过。
  1. /etc/portage/package.keywords
  2. sys-devel/prelink
复制代码

现在开始有趣的部分了。确定你已经做好了备份,一旦某环节出现问题的话没人担保有办法能恢复你的系统,除非重新安装Gentoo。
  1. # emerge binutils glibc
  2. # binutils-config -l
  3. # binutils-config # (Replace # with the corresponding number to binutils-2.17.50.0.3)
复制代码

现在添加"-Wl,--hash-style=both" 到/etc/make.conf文件中的LDFLAGS。如果你的文件中还没这行,请加入这样完整的一行。
  1. LDFLAGS="-Wl,--hash-style=both"
复制代码

现在我们用新的LDFLAGS来重新构筑系统,以确保每一部分都获得了新的.gnu.hash段。Portage会自动运行prelink,但是我不敢肯定它会百分百工作,所以我们需要继续手动进行prelink。
  1. # emerge -e world
  2. # emerge prelink
  3. # prelink -amR
复制代码

当这些完成以后你可以用readelf -a和grep GNU_HASH检查任意一个二进制程序,看是否工作。输出应该看起来象这样。
  1. # readelf -a /usr/bin/nano | grep GNU_HASH
  2.   [ 4] .gnu.hash         GNU_HASH         00000000004009a0  000009a0
  3. 0x000000006ffffef5 (GNU_HASH)           0x4009a0
复制代码


关于prelinking的更多信息可以看这里: http://www.gentoo.org/doc/en/prelink-howto.xm

从旧补丁升级到较新版本

对那些已经使用了旧补丁的人来说(20060705之前的),新补丁有不一致的hash,所以如果你不按照下面的步骤做的话你的系统有可能受损害。这个过程会使你的系统不可用。在此过程没完成之前请千万别关掉计算机的电源。

首先确认你已经有最新的 overlay,把 -Wl,--hash-style参数从 LDFLAGS中删掉,然后运行:
  1. # LD_X=1 emerge -1 coreutils binutils glibc
复制代码

再添加 -Wl,--hash-style=both到LDFLAGS中。
  1. # LD_X=1 emerge -e world
复制代码

现在安装prelink.
  1. # emerge prelink
  2. # prelink -amR
复制代码


这已经经过实验了。

从旧的bdirect/hashvals 升级到新的 hashstyle

首先需要从 /etc/make.conf的 LDFLAGS中移除 "-Wl,-Bdirect -Wl,-hashvals -Wl,-zdynsort"
然后emerge  portage中的glibc(没有补丁过的glibc)

  1. # PORTDIR_OVERLAY="" emerge -a1 glibc
复制代码


然后我们 用新的hashstyle use参数emerge binutils (从 portage) 和 glibc (从 overlay)。
        1请确保你正在emerge的binutils版本 >= 2.17.50.0.3,如果不是,请修改你的package.keywords
        2请为你的glibc添加hashstyle use参数(package.use)
  1. # LD_X=1 emerge -1 binutils glibc
复制代码


这已经测试成功了。(roderick 19:50, 31 July 2006 (UTC))

现在我们emerge/setup prelink(需要elfutils >= 0.122 、 prelink >= 20060712)
  1. # emerge prelink
  2. # prelink -amR
复制代码

记住rebuild结束后从环境变量中移除 LD_BIND_DIRECT="1",这是否会导致问题还不确定,但是最好还是这样做。很多人可能在把它加入了"/etc/env.d/99local"(或者可能在 /etc/env.d).

Post Messages

好了现在你应该用--hash-style=both来预链接系统了。如果一切正常的话你就没什么好做的了。如果你的系统挂掉了,很抱歉,不过我之前警告过你。

已知的问题


[edit]
Known Issues

>=binutils-2.17.50.0.10的话(老版本则不会).,<=madwifi-ng-0.9.2.1 (latest current version, Feb 11 2007 -- the cvs version too) 拒绝链接 (ld 不识别 hal.o 文件各式)  
要用的madwifi-ng 话你需要暂时降低你的 binutils 版本来编译它,然后它会正常工作的


=x11-drm-20070314 (最新版本有 unknown LDFLAGS的错误) (用 VIDEOCARDS="radeon"编译的,其他的没有测试) 简单的用 LDFLAGS=" " emerge 它。
[edit]
Troubleshooting

如果你的系统变糟了 当运行应用程序时得到一大堆符号错误,请使用 LD_X=1 命令.这会让你在解决问题之前暂时可以用这个程序。

I will post more in the Troubleshooting section regarding fixing a broken system soon.

The Gentoo Forums thread for hashstyle is: http://forums.gentoo.org/viewtopic-t-475538.html
+++++++++++++++++++++++++++++++++++++++++++++++++++++
大致翻译了一遍,因为专业不是这个,所以很多地方不知道翻译的对不对,大家凑合看,希望高手多指点。

=====================================================
据说效果挺明显的,我现在正emerge -e world中。。。
官方论坛有说fc6是用-Wl,--hash-style=gnu的,ubuntu的feisty据说也用的这个参数,就我的体验来说,feisty确实比edgy要快。
发表于 2007-3-21 03:13:27 | 显示全部楼层
好文
这个只会影响程序启动过程的速度,以及在程序中执行新功能的速度
对于已经执行了一定时间的进程的运行速度,这个hashstyle不会有太大影响
它只能加快符号解析速度,即加快动态连接速度
回复 支持 反对

使用道具 举报

发表于 2007-3-21 13:02:27 | 显示全部楼层
工程蛮浩大的,不知对程序的启动速度提高多少?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-3-21 16:39:02 | 显示全部楼层
http://gentoo-wiki.com/HOWTO_Hashstyle
这是地址,看着清楚些

"系统的性能最少能提高个5%-10%, 查找符号的性能更是最少提高了一倍。"
详见
http://steve.chinavfx.net/
回复 支持 反对

使用道具 举报

发表于 2007-3-21 17:13:01 | 显示全部楼层
wiki看过了,经不住诱惑,我也在emerge -e world,晚上就可以看到效果了。
回复 支持 反对

使用道具 举报

发表于 2007-3-22 07:05:27 | 显示全部楼层
现在开始有趣的部分了。确定你已经做好了备份,一旦某环节出现问题的话没人担保有办法能恢复你的系统,除非重新安装Gentoo。
  1. # emerge binutils glibc
  2. # binutils-config -l
  3. # binutils-config # (Replace # with the corresponding number to binutils-2.17.50.0.3)
复制代码
这里好像要选择特定的binutils版本,什么时候进~x86都不知道,下一个~x86版本会不会支持?如果portage中的binutils升级了怎么弄呢,锁定binutils不升级?这么大的动作,还是想等等:)
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-3-22 10:54:00 | 显示全部楼层
Post by zhou3345
这里好像要选择特定的binutils版本,什么时候进~x86都不知道,下一个~x86版本会不会支持?如果portage中的binutils升级了怎么弄呢,锁定binutils不升级?这么大的动作,还是想等等:)


对,选最新的。安装完最新的binutils后binutils-config -l 的输出最下面一个就是最新的,现在是sys-devel/binutils-2.17.50.0.13
然后binutils-config 2或者3 就switch过去了

有风险,不过我看官方论坛上好像很多人用
回复 支持 反对

使用道具 举报

发表于 2007-3-22 11:04:01 | 显示全部楼层
Post by 李这厮
对,选最新的。安装完最新的binutils后binutils-config -l 的输出最下面一个就是最新的,现在是sys-devel/binutils-2.17.50.0.13
然后binutils-config 2或者3 就switch过去了

有风险,不过我看官方论坛上好像很多人用

你编译完了吗?
我昨晚睡觉时有两个包没有编译过去,要不现在应该编译完了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-3-22 11:13:49 | 显示全部楼层
Post by zhoukb
你编译完了吗?
我昨晚睡觉时有两个包没有编译过去,要不现在应该编译完了。


system还没emerge完,差点
我硬盘上两个 gentoo,一个稳定的,一个不稳定的,专门用来实验^^ 这两天在稳定的这边下载东西呢
回复 支持 反对

使用道具 举报

发表于 2007-3-22 21:45:31 | 显示全部楼层
除了openoffice其他的包都编译完了,其中有十一的包编译不过,如下:
x11-libs/gtkglarea
app-text/openjade
x11-libs/vte
dev-cpp/libgnomecanvasmm
x11-terms/gnome-terminal
media-video/mplayer
dev-cpp/libgnomeuimm
app-cdr/cdrdao
media-sound/amarok
app-text/evince
media-sound/sound-juicer
错误都类似,其中x11-libs/gtkglarea的错误如下:
/usr/lib/libGLU.so: undefined reference to `operator delete(void*)@GLIBCXX_3.4'
/usr/lib/libGLU.so: undefined reference to `vtable for __cxxabiv1::__si_class_type_info@CXXABI_1.3'
/usr/lib/libGLU.so: undefined reference to `__gxx_personality_v0@CXXABI_1.3'
/usr/lib/libGLU.so: undefined reference to `operator delete[](void*)@GLIBCXX_3.4'
/usr/lib/libGLU.so: undefined reference to `operator new(unsigned int)@GLIBCXX_3.4'
/usr/lib/libGLU.so: undefined reference to `vtable for __cxxabiv1::__vmi_class_type_info@CXXABI_1.3'
/usr/lib/libGLU.so: undefined reference to `__cxa_pure_virtual@CXXABI_1.3'
/usr/lib/libGLU.so: undefined reference to `vtable for __cxxabiv1::__class_type_info@CXXABI_1.3'
/usr/lib/libGLU.so: undefined reference to `operator new[](unsigned int)@GLIBCXX_3.4'
collect2: ld returned 1 exit status
make[1]: *** [zktor] Error 1
make[1]: *** Waiting for unfinished jobs....
/usr/lib/libGLU.so: undefined reference to `operator delete(void*)@GLIBCXX_3.4'
/usr/lib/libGLU.so: undefined reference to `vtable for __cxxabiv1::__si_class_type_info@CXXABI_1.3'
/usr/lib/libGLU.so: undefined reference to `__gxx_personality_v0@CXXABI_1.3'
/usr/lib/libGLU.so: undefined reference to `operator delete[](void*)@GLIBCXX_3.4'
/usr/lib/libGLU.so: undefined reference to `operator new(unsigned int)@GLIBCXX_3.4'
/usr/lib/libGLU.so: undefined reference to `vtable for __cxxabiv1::__vmi_class_type_info@CXXABI_1.3'
/usr/lib/libGLU.so: undefined reference to `__cxa_pure_virtual@CXXABI_1.3'
/usr/lib/libGLU.so: undefined reference to `vtable for __cxxabiv1::__class_type_info@CXXABI_1.3'
/usr/lib/libGLU.so: undefined reference to `operator new[](unsigned int)@GLIBCXX_3.4'
collect2: ld returned 1 exit status
make[1]: *** [simple] Error 1
make[1]: Leaving directory `/usr/portage/distfiles/tmp/portage/x11-libs/gtkglarea-1.99.0/work/gtkglarea-1.99.0/examples'
make: *** [all-recursive] Error 1

!!! ERROR: x11-libs/gtkglarea-1.99.0 failed.
Call stack:
  ebuild.sh, line 1614:   Called dyn_compile
  ebuild.sh, line 971:   Called qa_call 'src_compile'
  environment, line 3634:   Called src_compile
  ebuild.sh, line 1304:   Called gnome2_src_compile
  gnome2.eclass, line 71:   Called die

请大家帮忙看看有什么解决办法?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表