我有一个测试共享库,其中包含一个功能:
int func(){return 1;}
我的主程序是
#ifdef NOPLT
#define _NOPLT __attribute__ ((noplt))
#else
#define _NOPLT
#endif
extern int func() _NOPLT;
int fun1(){
unsigned int i=0;
long j = 0;
while(++i) j+= func();
return j;
}
int main(int argc, char *argv[])
{
return fun1();
}
我将其编译如下:
pqy@pqy-E400:~/Desktop$ gcc t.c -fPIC -shared -o libt.so
pqy@pqy-E400:~/Desktop$ gcc m.c -g -o m_noplt -DNOPLT -L. -lt -Wl,-rpath=$PWD
pqy@pqy-E400:~/Desktop$ gcc m.c -g -o m_plt -L. -lt -Wl,-rpath=$PWD
然后测量每个程序的运行时间:
pqy@pqy-E400:~/Desktop$ time ./m_noplt;time ./m_noplt;time ./m_noplt
real 0m10.758s
user 0m10.758s
sys 0m0.000s
real 0m10.689s
user 0m10.689s
sys 0m0.000s
real 0m10.683s
user 0m10.683s
sys 0m0.000s
pqy@pqy-E400:~/Desktop$ time ./m_plt;time ./m_plt;time ./m_plt
real 0m10.041s
user 0m10.036s
sys 0m0.000s
real 0m9.958s
user 0m9.957s
sys 0m0.000s
real 0m9.970s
user 0m9.957s
sys 0m0.008s
看起来noplt比plt慢5%。 Gcc手册说: 函数foo上的noplt属性告诉编译器假定函数foo是在外部定义的,并且对foo的调用必须避免位置无关代码中的PLT。 在与位置相关的代码中,一些目标还将调用转换为标记为不使用PLT来使用GOT的函数。
像noplt这样的声音应该更快,因为它会跳过PLT。我弄错了吗?