连接器性能相关的交换空间? [英] Linker performance related to swap space?

查看:151
本文介绍了连接器性能相关的交换空间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是为您的书呆子快感难题。有时是很方便的
小样的东西与使用的一大块一点的C程序
静态存储器。虽然编程其中一个这样的程序,我注意到
改变到Fedora 15后程序采取了的的时间
编译。我们谈论30年代与0.1S。更奇怪的是,LD(中
连接器)是杏的CPU,慢慢开始吃所有可用
记忆。一些摆弄后,其中的细节我忘了,我管理
找到这个新的问题和我交换的规模之间的相关性
文件。下面是一个例子程序进行这个讨论的目的:

Here's a conundrum for your nerdy pleasure. Sometimes it's handy to mock up something with a little C program that uses a big chunk of static memory. While programming one these such programs, I noticed after changing to Fedora 15 the program took a long time to compile. We're talking 30s vs. 0.1s. Even more weird was that ld (the linker) was maxing out the CPU and slowly started eating all available memory. After some fiddling, the details of which I forget, I managed to find a correlation between this new problem and the size of my swap file. Here's an example program for the purposes of this discussion:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define M 1000000
#define GIANT_SIZE (200*M)

size_t g_arr[GIANT_SIZE];

int main( int argc, char **argv){   
    int i;
    for(i = 0; i<10; i++){
        printf("This should be zero: %d\n",g_arr[i]);
    }
    exit(1);
}

这方案有其具有约一个声明大小的巨型阵列
200 * 8MB的静态存储器= 1.6GB。编译这个程序需要一个
时间过多的:

This program has a giant array which has a declared size of about 200*8MB = 1.6GB of static memory. Compiling this program takes an inordinate amount of time:

[me@bleh]$ time gcc HugeTest.c 

real    0m12.954s
user    0m6.995s
sys 0m3.890s

[me@bleh]$

13S对于〜13行的C程序!?那是不对的。密钥号是
静态存储器空间的大小。只要它是比大
总的交换空间,它开始再次快速编译。例如,我
有交换空间5.3GB,因此更改GIANT_SIZE为(1000 * M)给出了
以下时间:

13s For a ~13 line C program!? That's not right. The key number is the size of the static memory space. As soon as it is larger than the total swap space, it starts to compile quickly again. For example, I have 5.3GB of swap space, so changing GIANT_SIZE to (1000*M) gives the following time:

[me@bleh]$ time gcc HugeTest.c 

real    0m0.087s
user    0m0.026s
sys 0m0.027s

嗯,这还差不多!为了进一步自己说服自己(如果
你在家里尝试这个),该交换空间的确是魔术
电话号码,我试图改变现有的交换空间,以一个真正的大型
19GB,并试图重新编译(1000 * M)版本:

Ah, that's more like it! To further convince myself (and yourself, if you're trying this at home) that swap space was indeed the magic number, I tried changing the available swap space to a truly massive 19GB and trying to compile the (1000*M) version again:

[me@bleh]$ ls -ali /extraswap 
5986 -rw-r--r-- 1 root root 14680064000 Jul 26 15:01 /extraswap
[me@bleh]$ sudo swapon /extraswap 
[me@bleh]$ time gcc HugeTest.c 

real    4m28.089s
user    0m0.016s
sys 0m0.010s

它没有4.5分钟后甚至是完整的! (请记住,亲爱的读者,
我有这个全部时间奉献给这个命令的运行,如
LD开始吃所有可用内存,然后开始交换,
有效地冻结了的计算机)。

It didn't even complete after 4.5 minutes! (Keep in mind, dear readers, I had to sacrifice this entire time to the running of that command, as ld begins to eat up all available memory then starts swapping, effectively freezing up the computer).

显然,链接器在这里做得不对,但我不知道该怎么
要解决这个以外重写程序或乱搞
与交换空间。我很想知道,如果有一个解决方案,或者如果我
在一些晦涩难懂的错误绊倒了。

Clearly the linker is doing something wrong here, but I don't know how to work around this other than rewriting the program or messing around with swap space. I'd love to know if there's a solution, or if I've stumbled upon some arcane bug.

顺便说一句,程序编译全部正确运行,独立于所有的掉期业务的。

By the way, the programs all compile and run correctly, independent of all the swap business.

有关参考,这里是一些可能相关的信息:

For reference, here is some possibly relevant information:

[]$ ulimit -a

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 27027
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

[]$ uname -r

2.6.40.6-0.fc15.x86_64

[]$ ld --version

GNU ld version 2.21.51.0.6-6.fc15 20110118
Copyright 2011 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

[]$ gcc --version

gcc (GCC) 4.6.1 20110908 (Red Hat 4.6.1-9)
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[]$ cat /proc/meminfo 
MemTotal:        3478272 kB
MemFree:         1749388 kB
Buffers:           16680 kB
Cached:           212028 kB
SwapCached:       368056 kB
Active:           489688 kB
Inactive:         942820 kB
Active(anon):     401340 kB
Inactive(anon):   803436 kB
Active(file):      88348 kB
Inactive(file):   139384 kB
Unevictable:          32 kB
Mlocked:              32 kB
SwapTotal:      19906552 kB
SwapFree:       17505120 kB
Dirty:               172 kB
Writeback:             0 kB
AnonPages:        914972 kB
Mapped:            60916 kB
Shmem:              1008 kB
Slab:              55248 kB
SReclaimable:      26720 kB
SUnreclaim:        28528 kB
KernelStack:        3608 kB
PageTables:        63344 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    21645688 kB
Committed_AS:   11208980 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      139336 kB
VmallocChunk:   34359520516 kB
HardwareCorrupted:     0 kB
AnonHugePages:    151552 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:      730752 kB
DirectMap2M:     2807808 kB

TL; DR:当一个C程序的(大)静态内存大于可用交换空间稍显不足,链接器将永远程序联系起来。然而,这是相当活泼的,当静态空间略微的放大的超过可用交换空间。这是怎么回事与!?

TL;DR: When the (large) static memory of a c program is slightly less than the available swap space, the linker takes forever to link the program. However, it's quite snappy when the static space is slightly larger than the available swap space. What's up with that!?

推荐答案

我能够重现这一个Ubuntu 10.10系统( GNU LD(GNU Binutils的为Ubuntu)51年2月​​20日,system.20100908上),我想我有你的答案。首先,一些方法。

I am able to reproduce this on an Ubuntu 10.10 system (GNU ld (GNU Binutils for Ubuntu) 2.20.51-system.20100908), and I think I have your answer. First, some methodology.

在确认这发生在我身上的一个小VM(512MB RAM,2GB交换),从这里我决定做会与strace GCC,看看到底发生了什么事时,一切去地狱的最简单的事情:

After confirming this happens to me in a small VM (512MB ram, 2GB swap), from here I decided the easiest thing to do would be to strace gcc and see what exactly was going on when everything went to hell:

~# strace -f gcc swap.c

它照亮了以下内容:

It illuminated the following:

vfork()                                 = 3589
[pid  3589] execve("/usr/lib/gcc/x86_64-linux-gnu/4.4.5/collect2", ["/usr/lib/gcc/x86_64-linux-gnu/4."..., "--build-id", "--eh-frame-hdr", "-m", "elf_x86_64", "--hash-style=gnu", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-o", "swap", "-z", "relro", "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., ...], [/* 26 vars */]) = 0

...

[pid  3589] vfork()                     = 3590

...

[pid  3590] execve("/usr/bin/ld", ["/usr/bin/ld", "--build-id", "--eh-frame-hdr", "-m", "elf_x86_64", "--hash-style=gnu", "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2", "-o", "swap", "-z", "relro", "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "/usr/lib/gcc/x86_64-linux-gnu/4."..., "-L/usr/lib/gcc/x86_64-linux-gnu/"..., ...], [/* 27 vars */]) = 0     

...

[pid  3590] lseek(13, 4096, SEEK_SET)   = 4096
[pid  3590] read(13, ".\4@\0\0\0\0\0>\4@\0\0\0\0\0N\4@\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
[pid  3590] mmap(NULL, 1600004096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f1771931000
<system comes to screeching halt>

这样看来,像我们可能会怀疑,它看起来像 LD 实际上是试图匿名 MMAP 该阵列的整个静态存储空间(或者可能是整个程序,这很难说,因为程序的其余部分是如此之小,它可能会全部装入额外4096)。

It would appear that, as we might have suspected, it looks like ld is actually trying to anonymously mmap the entire static memory space of this array (or possibly the entire program, it's hard to tell since the rest of the program is so small, it might all fit in that extra 4096).

所以,这一切都很好,但为什么当我们超出系统上可用的交换工作的呢?让我们把的swapoff 并运行 strace的-f 再次...

So that's all well and good, but why does it work when we exceed the available swap on the system? Let's turn swapoff and run strace -f again...

[pid  3618] lseek(13, 4096, SEEK_SET)   = 4096
[pid  3618] read(13, ".\4@\0\0\0\0\0>\4@\0\0\0\0\0N\4@\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096
[pid  3618] mmap(NULL, 1600004096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
[pid  3618] brk(0x60638000)             = 0x1046000
[pid  3618] mmap(NULL, 1600135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = -1 ENOMEM (Cannot allocate memory)
[pid  3618] mmap(NULL, 134217728, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0) = 0x7fd011864000

...

不出所料,LD似乎做它试图最后一次同样的事情,到的mmap整个空间。但该系统不再能够做到这一点,它失败! LD再次尝试,并再次失败,则劳工处没有什么意外......它使用较少的内存上移动。

Unsurprisingly, ld seems to do the same thing it tried last time, to mmap the entire space. but the system is no longer able to do that, it fails! ld tries again, and it fails again, then ld does something unexpected... it moves on with less memory.

奇怪,我想我们最好看看 LD code 即可。讨厌鬼,它不会做一个明确的 MMAP 。这必须从一个普通的老式的malloc 内到来。我们必须建立LD一些调试符号来跟踪下来。不幸的是,当我建彬-utils的2.21.1问题就走了。 Perhap它被固定在箱-utils的较新版本?

Weird, I guess we'd better have a look at the ld code then. Drat, it doesn't do an explicit mmap. This must be coming from inside of a plain old malloc. We'll have to build ld with some debug symbols to track this down. Unfortunately, when I built bin-utils 2.21.1 the problem went away. Perhap it's been fixed in newer versions of bin-utils?

这篇关于连接器性能相关的交换空间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆