Do chủ đề sử dụng bộ nhớ ảo hoặc bộ nhớ thực?


10

Tôi đã cố gắng tối ưu hóa máy chủ Linux của mình để xử lý 10.000 luồng trên mỗi tiến trình trong khi hiện tại chỉ có 382. Theo bài viết này , công thức sau đây được sử dụng để tìm ra tổng số chủ đề có thể:

number of threads = total virtual memory / (stack size*1024*1024)

Điều này có nghĩa là chủ đề lưu trữ tất cả dữ liệu của họ trong bộ nhớ ảo. Và theo hiểu biết tốt nhất của tôi, bộ nhớ ảo là không gian trao đổi trong một máy Linux được lưu trữ trên ổ cứng hơn RAM hoặc bộ nhớ cache.

Vì vậy, câu hỏi của tôi là chủ đề của chúng tôi sử dụng đĩa cứng để lưu trữ để xử lý / lưu trữ dữ liệu của nó.

Nếu có, thì hiệu ứng này không hiệu quả? Chúng ta có thể nâng cao hiệu suất bằng cách đưa chúng vào RAM hoặc bộ nhớ cache không? Làm sao?

Nếu không, làm thế nào chính xác làm việc chủ đề?

Cập nhật:

Theo câu trả lời vô dụng , bộ nhớ ảo là một hệ thống bao gồm:

  • bộ nhớ vật lý (RAM)
  • bất kỳ hoán đổi nào bạn đã đính kèm
  • hỗ trợ phần cứng để dịch các địa chỉ ảo sang địa chỉ vật lý và phát hành lỗi trang khi địa chỉ ảo không khả dụng trong bộ nhớ vật lý
  • (kernel) phần mềm hỗ trợ cho: quản lý các bảng tra cứu được sử dụng bởi phần cứng đó xử lý các lỗi trang đó bằng cách kéo các trang vào từ trao đổi theo yêu cầu

Do đó, mọi thứ trên bộ nhớ ảo đều được gọi chung là RAM (Bộ nhớ thực) và Đĩa cứng (Tệp hoán đổi). Và như James giải thích trong quyết định trả lời của mình về Ram vs HDD được Kernel thực hiện bằng các thuật toán như LRU.


2
trừ khi máy chủ của bạn có 10.000 CPU / lõi, bạn đang lãng phí thời gian.

@JarrodRoberson: Bất kỳ tại sao vậy?
dragosrsupercool

3
10.000 luồng không phải là một cách tốt để làm cho mọi thứ mở rộng quy mô, đó là một cách tốt để làm cho máy chủ thu thập dữ liệu, hơn 1 luồng trên mỗi CPU hoặc Core sẽ làm cho ngữ cảnh máy chủ chuyển đổi và chạy chậm hơn không nhanh hơn.

Cụ thể, khi bạn nói "cố gắng tối ưu hóa máy chủ Linux của tôi" - bạn đang cố gắng tối ưu hóa điều gì? Nếu đó là thông lượng, thì một luồng trên mỗi CPU có I / O ghép kênh và không chặn có thể sẽ tốt hơn.
Vô dụng

Câu trả lời:


12

theo hiểu biết tốt nhất của tôi, bộ nhớ ảo là không gian trao đổi trong máy Linux

Không, bộ nhớ ảo là một hệ thống bao gồm:

  • bộ nhớ vật lý (RAM)
  • bất kỳ hoán đổi nào bạn đã đính kèm
  • hỗ trợ phần cứng để dịch các địa chỉ ảo sang địa chỉ vật lý và phát hành lỗi trang khi địa chỉ ảo không khả dụng trong bộ nhớ vật lý
  • (kernel) hỗ trợ phần mềm cho:
    • quản lý các bảng tra cứu được sử dụng bởi phần cứng đó
    • xử lý các lỗi trang đó bằng cách kéo các trang vào từ trao đổi theo yêu cầu

Tùy thuộc vào kernel để đảm bảo bộ nhớ ảo bạn muốn được lưu vào RAM khi bạn muốn - trừ khi bạn viết lớp VM không gian người dùng của riêng bạn (như cơ sở dữ liệu thường làm, iiuc), đừng lo lắng về nó.


Ok vì vậy, giả định bộ nhớ ảo của tôi là sai. Dù sao một câu hỏi tiếp theo nhanh chóng .. Hiệu suất của các luồng tối đa được tải đầy đủ có bị ảnh hưởng nếu SWAP Space nhiều hơn RAM không?
dragosrsupercool

@dragosrsupercool: không gian hoán đổi của bạn sẽ luôn lớn hơn bộ nhớ vật lý, nếu không thì cần phải sử dụng bộ nhớ ảo.
Bryan Oakley

1
@BryanOakley: Điều đó không nhất thiết phải đúng. Một số hệ điều hành phân bổ một trang trao đổi cho mỗi trang ảo được phân bổ (nghĩa là trao đổi ít nhất phải lớn bằng vật lý). Các hệ điều hành khác chỉ phân bổ một trang trao đổi khi có nhu cầu di chuyển một trang ra khỏi bộ nhớ vật lý (nghĩa là trao đổi có thể nhỏ hơn vật lý). Ưu điểm của trước đây là nếu phân bổ thành công, sau đó hoán đổi bộ nhớ đó luôn thành công. Ưu điểm của cái sau là bạn không cần phải phân bổ một cách bi quan các tệp hoán đổi lớn để tính đến các tình huống tương đối hiếm.
mcmcc

1
@dragosrsupercool, hiệu suất sẽ không bị ảnh hưởng bởi dung lượng RAM, trao đổi hoặc tỷ lệ giữa chúng trừ khi bạn thiếu RAM và thực sự phân trang. sar có thể cho bạn biết về hoạt động phân trang iirc (đã kiểm tra: sar -Btrên Linux).
Vô dụng

@ Vô dụng: Tôi muốn tăng số lượng luồng cho đến khi tôi hoàn toàn sử dụng RAM và không bắt đầu phân trang.
dragosrsupercool

14

Nếu luồng thực sự đang chạy thì lệnh hiện tại và, bất kỳ biến nào mà luồng đang sử dụng phải nằm trong bộ nhớ vật lý.

Hầu hết (trên thực tế gần như tất cả) các chương trình nằm trong bộ nhớ ảo và, hầu hết các chương trình đều sử dụng bộ nhớ ảo để lưu trữ các biến.

Các địa chỉ ảo được tổ chức thành các khối được gọi là các trang (thường là các khối 4096 hoặc 8192 byte).

Tại bất kỳ thời điểm nào, mỗi khối bộ nhớ ảo được lưu trữ ở đâu đó trong bộ nhớ thực hoặc trên đĩa trong "không gian hoán đổi" dành riêng cho việc này.

Mã chương trình của bạn xử lý các địa chỉ ảo, khi bạn phân nhánh đến một địa chỉ ảo hoặc yêu cầu quyền truy cập vào bộ lưu trữ tại một địa chỉ ảo mà hệ thống (thường ở cấp phần cứng) định vị vị trí hiện tại của yêu cầu địa chỉ và ánh xạ tới địa chỉ ảo của bạn, nếu địa chỉ hiện đang nằm trên đĩa, nó sẽ đặt nó vào bộ nhớ thực và sau đó ánh xạ địa chỉ.

Rõ ràng là khi tất cả bộ nhớ vật lý đang được sử dụng nếu có thứ gì đó được phân trang thì phải loại bỏ thứ khác, vì vậy hệ thống sẽ tìm trang "Ít sử dụng gần đây nhất" và sao chép nó ra đĩa trước khi sao chép trang bạn yêu cầu.

Trong các hệ thống hiện đại, có một số tối ưu hóa và thủ thuật liên quan đến lưu trữ ảo.

  • Địa chỉ được ánh xạ trên cơ sở "theo quy trình", ví dụ, tất cả các chương trình C trong hộp Linux bắt đầu quy trình "chính" tại cùng một địa chỉ.
  • Điều này có thể cho phép một số quy trình 32 bit chiếm giữ và sử dụng nhiều hơn 4GB trên máy vì địa chỉ ảo 32 bit có thể được ánh xạ tới địa chỉ 64 bit thực.
  • Khi các tiến trình kết thúc hoặc bộ nhớ không "miễn phí", hệ thống chỉ đánh dấu các trang là miễn phí, chúng không bao giờ được sao chép trở lại đĩa trao đổi.
  • Tương tự như vậy khi một khối lưu trữ mới được yêu cầu, hệ thống chỉ cần lấy một trang miễn phí trong bộ nhớ thực, không, đĩa IO diễn ra.
  • Các chức năng ngủ và ngủ đông buộc tất cả bộ nhớ được sao chép vào không gian trao đổi để tất cả các quy trình hiện tại và có nội dung bộ nhớ hiện tại có thể được tạo lại khi thức dậy.

3
"Tất cả các chương trình C trong hộp Linux bắt đầu [chính] tại cùng một địa chỉ" dường như không tính đến ngẫu nhiên bố cục không gian địa chỉ. Điều đó được sử dụng ngày càng nhiều ngày nay để ngăn chặn các kế hoạch tấn công ngăn xếp khác nhau. Câu trả lời tốt khác, vì vậy +1.
một CVn

7

Trước hết, bạn cần đọc thêm về bộ nhớ máy tính , vì dường như bạn thiếu kiến ​​thức trong lĩnh vực đó.

Một luồng thực thi là đơn vị xử lý nhỏ nhất có thể được lên lịch bởi một hệ điều hành. Việc thực hiện các luồng và các tiến trình khác nhau từ một hệ điều hành này sang một hệ điều hành khác, nhưng trong hầu hết các trường hợp, một luồng được chứa trong một tiến trình. Nhiều luồng có thể tồn tại trong cùng một tiến trình và chia sẻ các tài nguyên như bộ nhớ, trong khi các tiến trình khác nhau không chia sẻ các tài nguyên này.

Vì vậy, các chủ đề sẽ sử dụng bộ nhớ có sẵn - bất kỳ loại nào có sẵn. Bạn có thể bắt đầu bao nhiêu luồng tùy thuộc vào kích thước bộ nhớ và dung lượng bộ nhớ cần thiết cho mỗi luồng. Nếu luồng sử dụng heap (không chỉ stack), thì nó cần nhiều bộ nhớ hơn và trong trường hợp đó bạn có thể bắt đầu ít luồng hơn.


@VJonvic: +1 để giải thích chủ đề cơ bản.
dragosrsupercool

6

Câu trả lời đơn giản cho câu hỏi của bạn là, họ sử dụng bộ nhớ ảo. mọi thứ đều sử dụng bộ nhớ ảo ngoại trừ một số ít các quy trình liên quan đến HĐH.

Mặt khác, khi luồng của bạn (hoặc bất kỳ luồng nào, trong bất kỳ quá trình nào) đang thực sự chạy, nó đang sử dụng bộ nhớ vật lý. Các trang bộ nhớ liên quan đến quá trình đó được hoán đổi vào bộ nhớ vật lý, nơi bộ xử lý thực hiện công việc của nó.


3

Bộ nhớ ảo là RAM của bạn cộng với không gian trao đổi của bạn. Ảo chỉ có nghĩa là địa chỉ mà chương trình của bạn nhìn thấy khác với địa chỉ mà chip RAM nhìn thấy. Nếu bạn cần truy cập bộ nhớ trong trao đổi, hệ điều hành sẽ chuyển nó vào RAM trước. Nếu bạn không muốn trao đổi, chỉ cần vô hiệu hóa nó. Nếu bạn có đủ RAM, bạn không thực sự cần nó.

Điều đó đang được nói, trừ khi bạn có bộ xử lý 10.000 lõi, tăng lên 10.000 luồng không thực sự là một "tối ưu hóa". Khi bạn có đủ luồng để tiêu thụ tất cả các lõi, cộng với một hoặc hai lần dự phòng khi các luồng đó bị chặn, việc thêm nhiều luồng sẽ làm giảm hiệu suất do lỗi chuyển đổi và bộ nhớ cache bị mất. Bạn vẫn có thể muốn sử dụng nhiều luồng hơn nếu nó làm cho logic chương trình của bạn đơn giản hơn, nhưng bạn sẽ giảm hiệu suất.


Có, 10.000 là quá nhiều vì máy chủ của tôi là máy lõi đơn 32 bit. Trên thực tế, các chủ đề không phải là điều tổng cpu. Chúng là các luồng của trình thu thập thông tin, vì vậy đôi khi chúng giống như chờ phản hồi của máy chủ. Tôi đặt mục tiêu đảm bảo cpu hoàn toàn bị chiếm dụng nhưng không quá tải hoặc quá tải. Nhưng tôi vẫn không hiểu làm thế nào tôi có thể biết CPU giống như miễn phí hay hoàn toàn bị chiếm đóng. Có công cụ hay lệnh nào không?
dragosrsupercool

Tôi nghĩ bạn có thể lấy thông tin đó từ toplệnh.
Karl Bielefeldt

@KarlBieledeldt: vâng, đó chính xác là những gì tôi đang tìm kiếm .. Một câu hỏi tiếp theo: Tôi chỉ có một ý tưởng để thu thập thông tin rằng nếu một số cách một luồng có thể gửi yêu cầu cho url trong khi luồng khác nhận được phản hồi của máy chủ thì tôi có thể giữ CPU sử dụng cao mà không sử dụng quá nhiều chủ đề. Điều đó có thể không? Giống như gửi yêu cầu từ một chủ đề trong khi nhận được phản hồi trên chủ đề khác?
dragosrsupercool

2

tối ưu hóa máy chủ Linux của tôi để xử lý 10.000 luồng trên mỗi tiến trình

Như những người khác giải thích, điều này nói chung là sai. Một luồng là một tài nguyên tốn kém , đáng chú ý là vì nó có ngăn xếp cuộc gọi riêng của nó (thường là một megabyte) và bởi vì nó là một tác vụ được lên lịch bởi kernel. Chủ đề thậm chí còn tốn kém hơn so với mô tả tập tin mở .

Đọc hệ điều hành: Three Easy Pieces (sách giáo khoa có thể tải xuống miễn phí).

Theo nguyên tắc thông thường, bạn không muốn có nhiều chủ đề và chắc chắn không có nhiều chủ đề có thể chạy được. Số lượng các luồng có thể chạy thường nên nhiều nhất là số lõi (hoặc một bội số nhỏ trong số đó), vì vậy nhiều nhất là khoảng một chục. Số lượng chủ đề trong một quy trình có thể lớn hơn một chút. Vì vậy, trừ khi bạn có một máy chủ rất rộng (có nhiều ổ cắm và lõi xử lý), bạn không muốn có hơn một chục luồng có thể chạy được và hàng trăm luồng (hầu hết chúng đều ở chế độ chờ) trên máy tính của bạn (trên máy tính để bàn của bạn) .

Trên Linux, các luồng và tiến trình rất giống nhau (vì cả hai có thể được tạo bởi clone (2) ) và cả hai đều là các tác vụ được lên lịch bởi kernel. Trên thực tế, bộ lập lịch kernel đang lên lịch các tác vụ có thể là các luồng trong một quy trình đa luồng hoặc luồng chính của một tiến trình đơn luồng (trong trường hợp đó, bạn sẽ đặt tên là "xử lý" luồng đơn đó) hoặc các luồng nhân. Bạn có thể không muốn có tổng cộng hơn một nghìn nhiệm vụ có thể lập lịch trên hệ thống máy tính để bàn của mình.

Trên Linux, một quy trình chỉ đơn giản là một nhóm các luồng chia sẻ cùng một không gian địa chỉ ảo (và chia sẻ một số thứ khác, chẳng hạn như bảng mô tả tệp, v.v ...). Một số quy trình chỉ có một luồng.

Một không gian địa chỉ ảo được định nghĩa bởi Wikipedia như

"tập hợp các dải địa chỉ ảo mà hệ điều hành cung cấp cho một tiến trình"

(nhưng cũng xem câu trả lời này giải thích rằng thuật ngữ này không phổ biến và một số tài liệu của Microsoft sử dụng một định nghĩa kháckhông tương thích ).

Trên Linux, Proc (5) rất hữu ích để hiểu không gian địa chỉ ảo của một số quy trình. Hãy thử cả hai
cat /proc/self/mapscat /proc/$$/mapstrong một thiết bị đầu cuối. Xem thêm điều nàypmap (1) & ps (1) & top (1) .

Tất cả các chương trình không gian người dùng đang chạy trong một số quy trình và sử dụng bộ nhớ ảo để mọi quy trình có không gian địa chỉ ảo riêng. Vật lý RAM là một nguồn lực bởi hạt nhân Linux được quản lý, và các ứng dụng không có quyền truy cập trực tiếp vào bộ nhớ RAM (trừ bởi mmap (2) -ing /dev/mem, xem mem (4) ).

Vì vậy, một quá trình không sử dụng RAM trực tiếp . Nó sử dụng bộ nhớ ảo và có không gian địa chỉ ảo riêng. Các hạt nhân sử dụng được phân trang để quản lý RAM vật lý trang và cung cấp không gian địa chỉ ảo và quá trình trừu tượng . Bất cứ lúc nào (ngay cả khi quá trình của bạn không hoạt động hoặc khi nó đang chạy), kernel có thể thoát ra một số trang (ví dụ: trao đổi chúng trên đĩa). Hạt nhân đang cấu hình MMU (và trang xử lý bỏ qua các ngoại lệ phần cứng trong một số trình xử lý ngắt , bằng cách tìm nạp trang từ đĩa hoặc bằng cách truyền lỗi phân đoạn cho quy trình, xem tín hiệu (7) )

Bạn có thể có các luồng màu xanh lá cây phía trên các luồng hệ thống (nhưng các thư viện luồng xanh rất khó thực hiện và gỡ lỗi). Nhìn vào những con khỉ đột được sử dụng trong Go cho một ví dụ lạ mắt. Xem thêm setcontext (3) .

Đôi khi, hệ thống của bạn có thể thử nghiệm đập . Điều này xảy ra khi tổng bộ nhớ ảo (cần thiết cho tất cả các quy trình) vượt quá - một yếu tố lớn - RAM vật lý khả dụng. Sau đó, máy tính của bạn trở nên không phản hồi. Đọc về kích thước tập hợp cư dân , phân trang theo yêu cầu , bộ làm việc , bộ nhớ thừa , ASLR .

Xem thêm -ví Linux- fork (2) , bản sao (2) , mmap (2) , madvise (2) , posix_fadvise (2) , mlock (2) , execve (2) , thông tin (7) , pthreads (7) , Futex (7) , khả năng (7) .

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.