Đôi khi, việc sử dụng một bộ nhớ tĩnh lớn có thể giúp bạn tạo ra một thứ gì đó với một chương trình C nhỏ. Tôi nhận thấy sau khi chuyển sang Fedora 15, chương trình mất thời gian dài để biên dịch. Chúng ta đang nói 30s so với 0.1s. Ngạc nhiên hơn nữa là ld (liên kết ) đã tối đa CPU và từ từ bắt đầu ăn tất cả bộ nhớ có sẵn . Sau khi một số khó khăn tôi quản lý để tìm một mối tương quan giữa vấn đề mới này và kích thước của tập tin hoán đổi của tôi . Dưới đây là một chương trình ví dụ cho các mục đích của cuộc thảo luận này:Hiệu suất của trình liên kết liên quan đến không gian hoán đổi?
#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);
}
Chương trình này có một mảng khổng lồ trong đó có một kích thước tuyên bố khoảng 200 * 8MB = 1.6GB bộ nhớ tĩnh. Biên soạn chương trình này có một lượng quá nhiều thời gian:
[[email protected]]$ time gcc HugeTest.c
real 0m12.954s
user 0m6.995s
sys 0m3.890s
[[email protected]]$
13s Đối với một ~ 13 dòng chương trình C !? Điều đó không đúng. Số khóa là kích thước của không gian bộ nhớ tĩnh. Ngay sau khi nó lớn hơn không gian hoán đổi tổng cộng , nó bắt đầu biên dịch lại nhanh chóng. Ví dụ, tôi có 5.3GB không gian trao đổi, vì vậy thay đổi GIANT_SIZE tới (1000 * M) cho gian sau:
[[email protected]]$ time gcc HugeTest.c
real 0m0.087s
user 0m0.026s
sys 0m0.027s
Ah, đó là giống như nó! Để tiếp tục thuyết phục bản thân mình (và chính mình, nếu bạn đang cố gắng ở nhà) không gian hoán đổi đó thực sự là số ma thuật , tôi đã thử thay đổi không gian hoán đổi có sẵn thành một số lớn thực sự là 19GB và cố gắng biên dịch (1000 * M) phiên bản một lần nữa:
[[email protected]]$ ls -ali /extraswap
5986 -rw-r--r-- 1 root root 14680064000 Jul 26 15:01 /extraswap
[[email protected]]$ sudo swapon /extraswap
[[email protected]]$ time gcc HugeTest.c
real 4m28.089s
user 0m0.016s
sys 0m0.010s
Nó thậm chí không hoàn thành sau 4,5 phút!
Rõ ràng mối liên kết đang làm điều gì đó sai ở đây, nhưng tôi không biết cách để làm việc xung quanh việc này ngoài viết lại chương trình hoặc gây rối xung quanh với không gian hoán đổi. Tôi rất muốn biết nếu có một giải pháp, hoặc nếu tôi đã vấp phải một số lỗi phức tạp.
Nhân tiện, các chương trình đều biên dịch và chạy một cách chính xác, độc lập với mọi hoạt động trao đổi.
Để tham khảo, dưới đây là một số thông tin có thể có liên quan:
[]$ 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: Khi (lớn) bộ nhớ tĩnh của chương trình ac là hơi ít hơn so với không gian hoán đổi có sẵn, các mối liên kết sẽ mãi mãi để liên kết chương trình. Tuy nhiên, nó khá linh hoạt khi không gian tĩnh hơi nhỏ hơn lớn hơn so với không gian hoán đổi có sẵn. Có chuyện gì thế !?
Sao y câu hỏi này: http://stackoverflow.com/questions/4978664/long-compilation-time-for-program-with-static-allocation –
@praetoriandroid Tuyệt vời tìm thấy, tôi xin lỗi tôi không thấy rằng sớm hơn. Câu trả lời trong câu hỏi đó giải thích lý do tại sao điều này có thể xảy ra, nhưng tôi sẽ chỉ ra điều gì đó hơn nữa mà câu hỏi của tôi ngụ ý - tại sao nó lại liên kết quá lớn so với không gian hoán đổi có sẵn? – Rooke
@Rooke: Có vẻ như khi không có đủ không gian hoán đổi, việc phân bổ toàn bộ đối tượng thất bại và trình liên kết rơi ngược lại trên một phương thức khác thực sự chạy nhanh hơn (do không nhúng vào trao đổi). – caf