Liên kết tĩnh so với liên kết động


399

Có bất kỳ lý do hiệu suất hấp dẫn để chọn liên kết tĩnh trên liên kết động hoặc ngược lại trong các tình huống nhất định? Tôi đã nghe hoặc đọc những điều sau đây, nhưng tôi không biết đủ về chủ đề để chứng minh tính chính xác của nó.

1) Sự khác biệt về hiệu suất thời gian chạy giữa liên kết tĩnh và liên kết động thường không đáng kể.

2) (1) không đúng nếu sử dụng trình biên dịch hồ sơ sử dụng dữ liệu hồ sơ để tối ưu hóa các đường dẫn chương trình vì với liên kết tĩnh, trình biên dịch có thể tối ưu hóa cả mã của bạn và mã thư viện. Với liên kết động chỉ mã của bạn có thể được tối ưu hóa. Nếu hầu hết thời gian dành cho việc chạy mã thư viện, điều này có thể tạo ra sự khác biệt lớn. Mặt khác, (1) vẫn được áp dụng.


59
"Với liên kết tĩnh, trình biên dịch có thể tối ưu hóa .. mã thư viện" nhưng chỉ khi nó biên dịch quá! Nếu bạn chỉ liên kết đến các tệp đối tượng được biên dịch trước, trình biên dịch của bạn sẽ không có cơ hội tối ưu hóa chúng.

3
Nếu đó là sự thật, thì bạn đã đúng, nhưng có một số câu hỏi là nó đúng như thế nào với trình biên dịch hiện đại, nếu ai đó có thể xác minh cách này hay cách khác, điều đó sẽ rất tuyệt.
Eloff

5
Với trình biên dịch biên dịch sang mã gốc (giống như hầu hết các trình biên dịch C / C ++), không có cơ hội tối ưu hóa mã nào nữa. Nếu mã được biên dịch sang một số ngôn ngữ trung gian (như .Net IL), trình biên dịch JIT sẽ được gọi khi thư viện đang được tải để biên dịch nó thành mã gốc. Quá trình biên dịch cuối cùng đó có thể ngày càng tốt hơn theo thời gian khi trình biên dịch JIT phát triển.
Tarydon

3
@Eloff: VS2008 thực hiện chính xác điều đó khi bật LTCG. (Tuy nhiên, các tệp lib trở nên rất lớn ..) Tôi đã chơi đùa với nó và với một người quan tâm đến "trình biên dịch của tôi có thể làm gì cho tôi", điều đó không có gì đáng kinh ngạc.
peterchen

Câu trả lời:


348
  • Liên kết động có thể giảm tổng mức tiêu thụ tài nguyên (nếu nhiều hơn một quy trình chia sẻ cùng một thư viện (tất nhiên bao gồm cả phiên bản "giống nhau"). Tôi tin rằng đây là đối số thúc đẩy sự hiện diện của nó trong hầu hết các môi trường. Ở đây "tài nguyên" bao gồm không gian đĩa, RAM và không gian bộ đệm. Tất nhiên, nếu trình liên kết động của bạn không đủ linh hoạt thì có nguy cơ địa ngục DLL .
  • Năng động, liên kết phương tiện mà sửa lỗi và nâng cấp thư viện tuyên truyền để cải thiện của bạn sản phẩm mà không đòi hỏi bạn phải vận chuyển bất cứ điều gì.
  • Plugin luôn gọi cho liên kết động .
  • Liên kết tĩnh , có nghĩa là bạn có thể biết mã sẽ chạy trong môi trường rất hạn chế (sớm trong quá trình khởi động hoặc trong chế độ cứu hộ).
  • Liên kết tĩnh có thể làm cho các nhị phân dễ dàng phân phối hơn đến các môi trường người dùng khác nhau (với chi phí gửi một chương trình đói tài nguyên lớn hơn và nhiều hơn).
  • Liên kết tĩnh có thể cho phép thời gian khởi động nhanh hơn một chút , nhưng điều này phụ thuộc vào một mức độ nào đó về cả quy mô và độ phức tạp của chương trình của bạn vào các chi tiết của chiến lược tải của HĐH.

Một số chỉnh sửa để bao gồm các đề xuất rất phù hợp trong các ý kiến ​​và trong các câu trả lời khác. Tôi muốn lưu ý rằng cách bạn phá vỡ điều này phụ thuộc rất nhiều vào môi trường bạn dự định chạy. Các hệ thống nhúng tối thiểu có thể không có đủ tài nguyên để hỗ trợ liên kết động. Các hệ thống nhỏ lớn hơn một chút có thể hỗ trợ liên kết động, vì bộ nhớ của chúng đủ nhỏ để tiết kiệm RAM từ liên kết động rất hấp dẫn. Các máy tính tiêu dùng đầy đủ có, như Mark lưu ý, tài nguyên khổng lồ và có lẽ bạn có thể để các vấn đề tiện lợi thúc đẩy suy nghĩ của bạn về vấn đề này.


Để giải quyết các vấn đề hiệu suất và hiệu quả: nó phụ thuộc .

Về mặt kinh điển, các thư viện động yêu cầu một loại lớp keo nào đó thường có nghĩa là gửi đôi hoặc thêm một lớp cảm ứng trong việc định địa chỉ hàm và có thể tốn một chút tốc độ (nhưng thời gian gọi hàm thực sự là một phần lớn trong thời gian chạy của bạn ???).

Tuy nhiên, nếu bạn đang chạy nhiều quy trình mà tất cả đều gọi cùng một thư viện, bạn có thể kết thúc việc lưu các dòng bộ đệm (và do đó chiến thắng khi chạy hiệu suất) khi sử dụng liên kết động so với sử dụng liên kết tĩnh. (Trừ khi các hệ điều hành hiện đại đủ thông minh để nhận thấy các phân đoạn giống hệt nhau trong các nhị phân được liên kết tĩnh. Có vẻ khó, có ai biết không?)

Một vấn đề khác: thời gian tải. Bạn trả chi phí tải tại một số điểm. Khi bạn trả chi phí này phụ thuộc vào cách hệ điều hành hoạt động cũng như liên kết bạn sử dụng. Có lẽ bạn nên ngừng trả tiền cho đến khi bạn biết bạn cần nó.

Lưu ý rằng liên kết tĩnh-động-động theo truyền thống không phải là vấn đề tối ưu hóa, bởi vì cả hai đều liên quan đến việc biên dịch riêng biệt xuống các tệp đối tượng. Tuy nhiên, điều này là không bắt buộc: về nguyên tắc, trình biên dịch có thể "biên dịch" "thư viện tĩnh" thành dạng AST được tiêu hóa và "liên kết" chúng bằng cách thêm các AST đó vào mã được tạo cho mã chính, do đó trao quyền tối ưu hóa toàn cầu. Không có hệ thống nào tôi sử dụng làm điều này, vì vậy tôi không thể nhận xét về mức độ hoạt động của nó.

Cách để trả lời các câu hỏi về hiệu suất luôn là bằng cách kiểm tra (và sử dụng môi trường kiểm tra càng giống môi trường triển khai càng tốt).


24
Tiêu thụ tài nguyên về cơ bản là không gian mã, mà thời gian trôi qua ngày càng ít được quan tâm. Nếu 500K thư viện được chia sẻ giữa 5 quy trình tiết kiệm 2 MB, ít hơn .1% của 3GB RAM.
Đánh dấu tiền chuộc

3
Nếu thư viện cũng chia sẻ cùng một ánh xạ ảo (cùng một địa chỉ vật lý và ảo trong tất cả các quy trình), thì không phải một liên kết động cũng lưu các khe TLB trong MMU của bộ xử lý?
Zan Lynx

6
Ngoài ra một liên kết động giúp dễ dàng cập nhật mã thư viện lỗi với các phiên bản tốt hơn.
Zan Lynx

89
@Zan Nó cũng giúp bạn dễ dàng thêm mã lỗi vào phiên bản hoạt động.

6
"Các plugin luôn kêu gọi liên kết động." Điều đó không chính xác. Một số mô hình plugin như AudioUnits của Apple có thể chạy plugin trong một quy trình riêng và sử dụng IPC. Đây là một sự thay thế an toàn hơn cho liên kết động cho các plugin (plugin không thể làm sập máy chủ). Đề xuất câu trả lời được cập nhật thành "Plugin có thể yêu cầu liên kết động" hoặc tương tự.
Taylor

68

1) dựa trên thực tế là việc gọi hàm DLL luôn sử dụng bước nhảy gián tiếp bổ sung. Ngày nay, điều này thường không đáng kể. Bên trong DLL có thêm một số chi phí trên CPU i386, vì chúng không thể tạo mã độc lập vị trí. Trên amd64, các bước nhảy có thể liên quan đến bộ đếm chương trình, vì vậy đây là một cải tiến rất lớn.

2) Điều này đúng. Với tối ưu hóa được hướng dẫn bằng cách định hình, bạn thường có thể giành được hiệu suất khoảng 10-15 phần trăm. Bây giờ tốc độ CPU đã đạt đến giới hạn của nó, nó có thể đáng để làm điều đó.

Tôi sẽ thêm: (3) trình liên kết có thể sắp xếp các chức năng trong một nhóm hiệu quả bộ đệm hơn, do đó các lỗi bộ nhớ cache đắt tiền được giảm thiểu. Nó cũng có thể đặc biệt ảnh hưởng đến thời gian khởi động của các ứng dụng (dựa trên kết quả tôi đã thấy với trình biên dịch Sun C ++)

Và đừng quên rằng với DLL, không thể loại bỏ mã chết. Tùy thuộc vào ngôn ngữ, mã DLL có thể không tối ưu. Các hàm ảo luôn là ảo vì trình biên dịch không biết liệu máy khách có ghi đè lên nó hay không.

Vì những lý do này, trong trường hợp không có nhu cầu thực sự về DLL, thì chỉ cần sử dụng biên dịch tĩnh.

EDIT (để trả lời bình luận, bởi người dùng gạch dưới)

Đây là một tài nguyên tốt về vấn đề mã độc lập vị trí http://eli.thegreenplace.net/2011/11/03/poseition-indeperee-code-pic-in-spl-lologists/

Như đã giải thích x86 không có chúng AFAIK cho bất cứ điều gì khác sau đó phạm vi nhảy 15 bit và không cho các bước nhảy và cuộc gọi vô điều kiện. Đó là lý do tại sao các chức năng (từ máy phát điện) có hơn 32K luôn là một vấn đề và cần đến các tấm bạt lò xo nhúng.

Nhưng trên HĐH x86 phổ biến như Linux, bạn không cần quan tâm nếu tệp .so / DLL không được tạo bằng gcckhóa chuyển -fpic(thực thi việc sử dụng các bảng nhảy gián tiếp). Bởi vì nếu bạn không làm vậy, mã chỉ được sửa như một trình liên kết thông thường sẽ di chuyển nó. Nhưng trong khi thực hiện điều này, nó làm cho phân đoạn mã không thể chia sẻ được và nó sẽ cần ánh xạ toàn bộ mã từ đĩa vào bộ nhớ và chạm vào tất cả trước khi có thể sử dụng (làm trống hầu hết các bộ đệm, nhấn TLB), v.v. khi điều này được coi là chậm.

Vì vậy, bạn sẽ không có bất kỳ lợi ích nữa.

Tôi không nhớ lại những gì hệ điều hành (Solaris hoặc FreeBSD) đã cho tôi vấn đề với xây dựng hệ thống Unix của tôi vì tôi chỉ là không làm điều này và tự hỏi tại sao nó bị rơi cho đến khi tôi áp dụng -fPICđể gcc.


4
Tôi thích câu trả lời này, vì đó là người duy nhất giải quyết những điểm tôi nêu ra trong câu hỏi.
Eloff

Sẽ rất thú vị khi có các tài liệu tham khảo về các kỹ thuật DLL đó và so sánh giữa các hệ điều hành khác nhau.
ChúZeiv

Có vẻ tốt, nhưng tốc độ CPU chắc chắn không đạt đến giới hạn của nó.
Aidiakapi

67

Liên kết động là cách thực tế duy nhất để đáp ứng một số yêu cầu cấp phép như LGPL .


17
Miễn là người dùng cuối có thể xem lại mã LGPL'd (ví dụ: vì bạn cung cấp mã nguồn hoặc các tệp đối tượng được biên dịch cùng với phần mềm của bạn), thì liên kết tĩnh là ổn . Ngoài ra, nếu phần mềm của bạn được sử dụng nội bộ (nghĩa là chỉ được sử dụng trong tổ chức của bạn và không được phân phối), thì bạn có thể liên kết tĩnh. Điều này sẽ áp dụng cho phần mềm máy chủ, nơi máy chủ không được phân phối.
JBentley

3
Đừng hiểu điều đó. Bạn có thể cho tôi thêm nguồn (hoặc giải thích thêm) để đánh giá cao những gì bạn đã viết không?
Baskaya

4
@Thorn xem phần giấy phép LGPL 4.d + e . Bạn cần phân phối dưới dạng yêu cầu người dùng thực hiện liên kết hoặc phân phối thư viện dùng chung (động).
Đánh dấu tiền chuộc

46

Tôi đồng ý với các điểm mà dnmckee đề cập, cộng thêm:

  • Các ứng dụng được liên kết tĩnh có thể dễ dàng triển khai hơn, vì có ít hoặc không có phụ thuộc tệp bổ sung (dll / .so) có thể gây ra sự cố khi chúng bị thiếu hoặc cài đặt sai vị trí.

6
Điều đáng chú ý là trình biên dịch Go từ Google sẽ chỉ biên dịch tĩnh các mã nhị phân vì lý do này.
Hut8

34

Một lý do để thực hiện một bản dựng được liên kết tĩnh là để xác minh rằng bạn đã đóng hoàn toàn cho tệp thực thi, tức là tất cả các tham chiếu ký hiệu được giải quyết chính xác.

Là một phần của một hệ thống lớn đang được xây dựng và thử nghiệm bằng cách tích hợp liên tục, các thử nghiệm hồi quy hàng đêm được chạy bằng phiên bản liên kết tĩnh của các tệp thực thi. Đôi khi, chúng ta sẽ thấy rằng một biểu tượng sẽ không giải quyết được và liên kết tĩnh sẽ thất bại mặc dù thực thi được liên kết động sẽ liên kết thành công.

Điều này thường xảy ra khi các biểu tượng được đặt sâu trong các lib được chia sẻ có tên sai chính tả và do đó sẽ không liên kết tĩnh. Trình liên kết động không giải quyết hoàn toàn tất cả các biểu tượng, bất kể sử dụng đánh giá theo chiều sâu hay trước tiên, do đó bạn có thể hoàn thành với một thực thi được liên kết động mà không đóng hoàn toàn.


1
Điểm rất tốt, tôi đã cố gắng thực hiện điều này gần đây với một số mã tôi có trong công việc nhưng biên dịch mọi thứ một cách tĩnh lặng tỏ ra khó chịu một cách đáng ngạc nhiên và tôi đã từ bỏ
ChúZeiv

21

1 / Tôi đã tham gia vào các dự án trong đó liên kết động so với liên kết tĩnh được điểm chuẩn và sự khác biệt không được xác định đủ nhỏ để chuyển sang liên kết động (Tôi không phải là một phần của thử nghiệm, tôi chỉ biết kết luận)

2 / Liên kết động thường được liên kết với PIC (Mã độc lập vị trí, mã không cần sửa đổi tùy thuộc vào địa chỉ mà nó được tải). Tùy thuộc vào kiến ​​trúc PIC có thể mang lại sự chậm chạp khác nhưng cần thiết để có được lợi ích của việc chia sẻ thư viện được liên kết động giữa hai thực thi (và thậm chí hai quá trình thực thi giống nhau nếu HĐH sử dụng ngẫu nhiên địa chỉ tải làm biện pháp bảo mật). Tôi không chắc chắn rằng tất cả các hệ điều hành đều cho phép tách hai khái niệm này, nhưng Solaris và Linux cũng vậy và ISTR mà HP-UX cũng làm như vậy.

3 / Tôi đã tham gia vào các dự án khác sử dụng liên kết động cho tính năng "bản vá dễ dàng". Nhưng "bản vá dễ dàng" này làm cho việc phân phối sửa chữa nhỏ dễ dàng hơn một chút và trở thành một cơn ác mộng phiên bản. Chúng tôi thường kết thúc bằng cách phải đẩy tất cả mọi thứ cộng với việc phải theo dõi các vấn đề tại trang web của khách hàng vì phiên bản sai là mã thông báo.

Kết luận của tôi là tôi đã sử dụng liên kết tĩnh ngoại trừ:

  • cho những thứ như plugin phụ thuộc vào liên kết động

  • khi chia sẻ là quan trọng (các thư viện lớn được sử dụng bởi nhiều quy trình cùng lúc như thời gian chạy C / C ++, thư viện GUI, ... thường được quản lý độc lập và theo đó ABI được xác định nghiêm ngặt)

Nếu một người muốn sử dụng "bản vá dễ dàng", tôi cho rằng các thư viện phải được quản lý như các thư viện lớn ở trên: chúng phải gần như độc lập với ABI đã xác định không được thay đổi bằng các bản sửa lỗi.


1
Một số hệ điều hành cho các bộ xử lý PIC không phải PIC hoặc đắt tiền sẽ chuẩn bị các thư viện động được tải tại một địa chỉ cụ thể trong bộ nhớ và nếu chúng có thể làm điều đó, chúng chỉ cần ánh xạ trong một bản sao của thư viện tới mọi quy trình liên kết với nó. Điều đó làm giảm chi phí của PIC rất nhiều. Ít nhất OS X và một số bản phân phối Linux làm điều này, tôi không chắc về Windows.
Andrew McGregor

Cảm ơn Andrew, tôi không biết rằng một số bản phân phối Linux đã sử dụng cái này. Bạn có một tài liệu tham khảo tôi có thể theo dõi hoặc một từ khóa tôi có thể tìm kiếm để tìm hiểu thêm? (FWIW Tôi đã nghe nói rằng Windows đang thực hiện một biến thể của điều này, nhưng Windows quá xa khả năng của tôi khi tôi đề cập đến nó).
Lập trình viên

Tôi nghĩ rằng từ khóa bạn đang tìm kiếm là "prelink" - nó chuẩn bị một thư viện sẽ được tải nhanh chóng tại một địa chỉ nhất định, để làm cho chương trình khởi động nhanh hơn.
Blaisorblade

20

Điều này thảo luận rất chi tiết về các thư viện chia sẻ trên linux và ý nghĩa hiệu suất.


3
+1 để liên kết với DSO của Drepper, mà mọi người tạo thư viện trên Linux nên đọc.
janneb

10

Trên các hệ thống giống như Unix, liên kết động có thể khiến 'root' khó sử dụng một ứng dụng với các thư viện dùng chung được cài đặt ở các vị trí ngoài luồng. Điều này là do trình liên kết động thường không chú ý đến LD_LIBRARY_PATH hoặc tương đương với các quy trình có đặc quyền gốc. Đôi khi, sau đó, liên kết tĩnh tiết kiệm trong ngày.

Ngoài ra, quá trình cài đặt phải xác định vị trí các thư viện, nhưng điều đó có thể gây khó khăn cho nhiều phiên bản phần mềm cùng tồn tại trên máy.


1
Điểm LD_LIBRARY_PATHchính xác không phải là một trở ngại cho việc sử dụng các thư viện dùng chung, ít nhất là không phải trong GNU / Linux. Ví dụ: nếu bạn đặt các thư viện dùng chung trong thư mục ../lib/liên quan đến tệp chương trình, thì với chuỗi công cụ GNU, tùy chọn liên kết -rpath $ORIGIN/../libsẽ chỉ định tìm kiếm thư viện từ vị trí tương đối đó. Sau đó, bạn có thể dễ dàng di chuyển ứng dụng cùng với tất cả các thư viện chia sẻ liên quan. Sử dụng thủ thuật này, không có vấn đề gì khi có nhiều phiên bản của ứng dụng và thư viện (giả sử chúng có liên quan, nếu không bạn có thể sử dụng các liên kết tượng trưng).
FooF

> cho các quy trình với quyền root. Tôi nghĩ rằng bạn đang nói về các chương trình setuid chạy từ người dùng không phải root - nếu không thì điều đó vô nghĩa. Và một nhị phân setuid với các thư viện ở các vị trí không chuẩn là lạ - nhưng vì chỉ root mới có thể cài đặt các chương trình đó, nên anh ta cũng có thể chỉnh sửa /etc/ld.so.confcho trường hợp đó.
Blaisorblade

10

Nó là khá đơn giản, thực sự. Khi bạn thực hiện thay đổi trong mã nguồn của mình, bạn có muốn đợi 10 phút để mã đó được xây dựng hoặc 20 giây không? Hai mươi giây là tất cả những gì tôi có thể đưa ra. Ngoài ra, tôi hoặc rút thanh kiếm ra hoặc bắt đầu suy nghĩ về cách tôi có thể sử dụng việc biên dịch và liên kết riêng biệt để đưa nó trở lại vùng thoải mái.


1
Tôi chưa thực sự đánh giá sự khác biệt về tốc độ biên dịch, nhưng tôi sẽ liên kết động nếu nó nhanh hơn đáng kể. Boost làm đủ những điều xấu cho thời gian biên dịch của tôi.
Eloff

9

Ví dụ tốt nhất cho liên kết động là, khi thư viện phụ thuộc vào phần cứng được sử dụng. Vào thời cổ đại, thư viện toán học C được quyết định là động, do đó mỗi nền tảng có thể sử dụng tất cả các khả năng của bộ xử lý để tối ưu hóa nó.

Một ví dụ tốt hơn nữa có thể là OpenGL. OpenGl là một API được AMD và NVidia triển khai khác nhau. Và bạn không thể sử dụng triển khai NVidia trên thẻ AMD, vì phần cứng khác nhau. Bạn không thể liên kết OpenGL tĩnh với chương trình của mình, vì điều đó. Liên kết động được sử dụng ở đây để cho phép API được tối ưu hóa cho tất cả các nền tảng.


8

Liên kết động đòi hỏi thêm thời gian để HĐH tìm thư viện động và tải nó. Với liên kết tĩnh, mọi thứ đều kết hợp với nhau và đó là tải một lần vào bộ nhớ.

Ngoài ra, xem DLL Hell . Đây là kịch bản mà DLL mà HĐH tải không phải là kịch bản đi kèm với ứng dụng của bạn hoặc phiên bản mà ứng dụng của bạn mong đợi.


1
Điều quan trọng cần lưu ý là có một loạt các biện pháp đối phó để tránh DLL Hell.
ocodo

5

Một vấn đề khác chưa được thảo luận là sửa lỗi trong thư viện.

Với liên kết tĩnh, bạn không chỉ phải xây dựng lại thư viện mà còn phải xem lại và phân phối lại tệp thực thi. Nếu thư viện chỉ được sử dụng trong một lần thực thi, điều này có thể không thành vấn đề. Nhưng càng nhiều thực thi cần phải được xem xét lại và phân phối lại, nỗi đau càng lớn.

Với liên kết động, bạn chỉ cần xây dựng lại và phân phối lại thư viện động và bạn đã hoàn thành.


2

liên kết tĩnh chỉ cung cấp cho bạn một exe duy nhất, inorder để thực hiện thay đổi mà bạn cần biên dịch lại toàn bộ chương trình của mình. Trong khi liên kết động, bạn chỉ cần thay đổi dll và khi bạn chạy exe, các thay đổi sẽ được chọn trong thời gian chạy. Dễ dàng hơn để cung cấp các bản cập nhật và sửa lỗi bằng liên kết động (ví dụ: windows).


2

Có một số lượng lớn các hệ thống ngày càng tăng trong đó một mức độ cực cao của liên kết tĩnh có thể có tác động tích cực rất lớn đến các ứng dụng và hiệu năng hệ thống.

Tôi đề cập đến cái thường được gọi là "hệ thống nhúng", nhiều hệ thống hiện đang ngày càng sử dụng các hệ điều hành có mục đích chung và các hệ thống này được sử dụng cho mọi thứ có thể tưởng tượng được.

Một ví dụ cực kỳ phổ biến là các thiết bị sử dụng hệ thống GNU / Linux sử dụng Busybox . Tôi đã đưa điều này đến cùng cực với NetBSD bằng cách xây dựng hình ảnh hệ thống i386 (32 bit) có thể khởi động, bao gồm cả kernel và hệ thống tập tin gốc của nó, cái sau chứa một crunchgennhị phân liên kết tĩnh (by ) với các liên kết cứng tất cả các chương trình mà bản thân nó chứa tất cả (cũng ở mức cuối cùng là 274) của các chương trình hệ thống tính năng đầy đủ tiêu chuẩn (hầu hết ngoại trừ chuỗi công cụ) và nó nhỏ hơn 20 mega byte trong kích thước (và có lẽ chạy rất thoải mái trong một hệ thống chỉ với 64MB của bộ nhớ (ngay cả với hệ thống tập tin gốc không bị nén và hoàn toàn trong RAM), mặc dù tôi không thể tìm thấy một bộ nhớ quá nhỏ để kiểm tra nó).

Nó đã được đề cập trong các bài viết trước đó rằng thời gian khởi động của các nhị phân được liên kết tĩnh nhanh hơn (và nó có thể nhanh hơn rất nhiều ), nhưng đó chỉ là một phần của bức tranh, đặc biệt là khi tất cả các mã đối tượng được liên kết vào cùng và thậm chí nhiều hơn, đặc biệt là khi hệ điều hành hỗ trợ phân trang theo yêu cầu của mã trực tiếp từ tệp thực thi. Trong kịch bản lý tưởng này, thời gian khởi động của các chương trình theo nghĩa đen là không đáng kể vì hầu hết tất cả các trang mã sẽ có trong bộ nhớ và được sử dụng bởi trình bao (vàinit bất kỳ quá trình nền khác mà có thể được chạy), ngay cả khi chương trình yêu cầu có không đã từng được chạy kể từ khi khởi động vì có lẽ chỉ cần tải một trang bộ nhớ để đáp ứng các yêu cầu thời gian chạy của chương trình.

Tuy nhiên đó vẫn chưa phải là toàn bộ câu chuyện. Tôi cũng thường xây dựng và sử dụng các cài đặt hệ điều hành NetBSD cho các hệ thống phát triển đầy đủ của mình bằng cách liên kết tĩnh tất cả các nhị phân. Mặc dù điều này cần nhiều dung lượng đĩa hơn (tổng cộng ~ 6,6 GB cho x86_64 với mọi thứ, bao gồm cả chuỗi công cụ và liên kết tĩnh X11) (đặc biệt nếu một bảng giữ biểu tượng gỡ lỗi đầy đủ có sẵn cho tất cả các chương trình khác ~ 2,5 GB), kết quả vẫn chạy tổng thể nhanh hơn và đối với một số tác vụ thậm chí sử dụng ít bộ nhớ hơn so với hệ thống được liên kết động thông thường để chia sẻ các trang mã thư viện. Đĩa rất rẻ (thậm chí là đĩa nhanh) và bộ nhớ để lưu các tệp đĩa được sử dụng thường xuyên cũng tương đối rẻ, nhưng chu kỳ CPU thực sự thì không, và trả tiềnld.so chi phí khởi động cho mọi quá trình bắt đầu mọithời gian bắt đầu sẽ mất hàng giờ đồng hồ của chu kỳ CPU khỏi các tác vụ yêu cầu bắt đầu nhiều quy trình, đặc biệt là khi các chương trình tương tự được sử dụng lặp đi lặp lại, chẳng hạn như trình biên dịch trên hệ thống phát triển. Các chương trình chuỗi công cụ được liên kết tĩnh có thể giảm thời gian xây dựng đa kiến ​​trúc cho toàn hệ thống của tôi theo giờ . Tôi vẫn chưa xây dựng chuỗi công cụ thành crunchgennhị phân đơn của mình , nhưng tôi nghi ngờ khi tôi làm sẽ có nhiều giờ hơn thời gian xây dựng vì chiến thắng cho bộ đệm CPU.


2

Liên kết tĩnh bao gồm các tệp mà chương trình cần trong một tệp thực thi duy nhất.

Liên kết động là những gì bạn sẽ xem xét thông thường, nó làm cho một tệp thực thi vẫn yêu cầu DLL và như vậy phải nằm trong cùng một thư mục (hoặc DLL có thể nằm trong thư mục hệ thống).

(DLL = liên kết động thư viện )

Các tệp thực thi được liên kết động được biên dịch nhanh hơn và không nặng về tài nguyên.


0

Static linking là một quá trình trong thời gian biên dịch khi một nội dung được liên kết được sao chép vào nhị phân chính và trở thành một nhị phân đơn.

Nhược điểm:

  • thời gian biên dịch dài hơn
  • nhị phân đầu ra lớn hơn

Dynamic linkinglà một quá trình trong thời gian chạy khi một nội dung được liên kết được tải. Kỹ thuật này cho phép:

  • nâng cấp nhị phân được liên kết mà không biên dịch lại bản chính giúp tăng ABItính ổn định [Giới thiệu]
  • có một bản sao được chia sẻ

Nhược điểm:

  • thời gian bắt đầu chậm hơn (nội dung được liên kết nên được sao chép)
  • lỗi liên kết được ném trong thời gian chạy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.