Giới hạn lõi cpu python

Tên tôi là Joan, đây là tin nhắn đầu tiên của tôi trong cộng đồng Python và tôi muốn hỏi bạn một số nghi ngờ về ý nghĩa của hai trong số các đối số từ lớp Pool. "quy trình" và "maxtasksperchild"

  1. “quy trình”. Theo như tôi được biết, đối số này cho phép người dùng giới thiệu số lượng bộ xử lý [lõi từ CPU] trong đó các quy trình khác nhau sẽ phân chia. Trong trường hợp của tôi, tôi có sẵn 32 bộ xử lý. Để tò mò, tôi đã đặt "các quy trình" thành một số cao hơn 32 và tập lệnh Python vẫn hoạt động tốt. Vì vậy, một trong những câu hỏi của tôi là. trong trường hợp này, tại sao chương trình vẫn hoạt động mặc dù tôi đã đặt giá trị "quy trình" không có ý nghĩa gì? . Trong trường hợp này, tập lệnh Python không hoạt động tốt và OSError đã được khởi chạy, cụ thể là "Quá nhiều tệp đã mở". Vì vậy, câu hỏi thứ hai của tôi là, tại sao chương trình không hoạt động trong tình huống này?

2] “maxtasksperchild”. Trong trang web tài liệu Python, nó nói rằng maxtasksperchild là số lượng tác vụ mà một quy trình công nhân có thể hoàn thành trước khi nó thoát và được thay thế bằng một quy trình công nhân mới, để cho phép giải phóng các tài nguyên không sử dụng. maxtasksperchild mặc định là None , có nghĩa là worker process sẽ tồn tại miễn là pool. Tôi sẽ rất vui nếu bạn có thể chỉ cho tôi một ví dụ thực tế về việc sử dụng đối số này và xem những lợi ích từ việc sử dụng nó

Cám ơn rất nhiều

Xin chào Joan,

Đối số "quy trình" không phải là số lượng lõi CPU được sử dụng. Đó là số lượng quy trình, không phải bộ xử lý

Tiến trình. Quy trình [máy tính] - Wikipedia

Không phải bộ xử lý. Bộ xử lý trung tâm - Wikipedia

Hiện tại, máy tính của tôi có khoảng 290 quy trình đang chạy và CPU của tôi chỉ có bốn lõi. 13 trong số các quy trình đó là từ riêng Firefox

Mọi hệ điều hành đều có giới hạn về số lượng tiến trình đang chạy. Đối với PC nhỏ của tôi, 290 không phải là nhiều. Ngay cả đối với máy tính của bạn, máy 32 lõi mạnh hơn, 10000 quy trình là quá nhiều và khi bạn cố gắng tạo tất cả 10000 quy trình cùng một lúc, hệ điều hành sẽ thông báo KHÔNG và bạn gặp lỗi OSError

Bạn đang chạy hệ điều hành nào? . Ngay cả Linux 32 bit cũng có tối đa 32768. Vậy tại sao mã của bạn không thành công chỉ với 10000?

Đoán từ thông báo lỗi bạn nhận được, tôi nghĩ rằng đây là giới hạn nội bộ. Có vẻ như Pool cố mở tệp cho từng quy trình worker. Mọi hệ điều hành đều có giới hạn về số lượng tệp đang mở và giới hạn đó nhỏ hơn nhiều. Vì vậy, khi quy trình Python đang chạy [theo mặc định] mở 1024 tệp, nó không thể mở thêm bất kỳ tệp nào nữa và do đó bạn gặp lỗi OSError mà bạn đã thấy

Lưu ý rằng có nhiều quy trình hơn không phải lúc nào cũng tốt hơn. Cần có tài nguyên hệ điều hành [thời gian và bộ nhớ] để chạy từng quy trình và bạn càng có nhiều quy trình thì hệ điều hành càng phải làm nhiều việc hơn để quản lý chúng. Tại một số điểm, HĐH đang thực hiện nhiều công việc quản lý các quy trình hơn là bạn đang nhận được lợi ích từ đa xử lý và thay vì nhanh hơn, mã của bạn lại chậm hơn

Điều này cũng xảy ra trong cuộc sống thực. Bạn đã bao giờ thấy nhà bếp của một nhà hàng bận rộn chưa? . Thêm đầu bếp thứ hai có nghĩa là họ có thể chuẩn bị nhiều thức ăn nhanh hơn. Thêm đầu bếp thứ ba, có thể là thứ tư, nhưng cuối cùng [ví dụ, mười hoặc hai mươi hoặc năm mươi đầu bếp, tùy thuộc vào độ lớn của nhà bếp] họ cản trở nhau và làm việc kém hiệu quả hơn. Ngay cả căn bếp lớn nhất cũng không hoạt động tốt với 10000 đầu bếp chen chúc

Tôi không thể trả lời câu hỏi của bạn về maxtasksperchild. Tôi không biết bất kỳ ví dụ thực tế nào để chỉ cho bạn

Nhưng tôi tưởng tượng đối số maxtasksperchild tồn tại trong trường hợp các quy trình worker của bạn đang chạy mã làm rò rỉ tài nguyên [bộ nhớ, bộ mô tả tệp mở, v.v.]. Bạn có thể yêu cầu mỗi worker process thoát ra sau một số tác vụ nhất định, để HĐH có thể lấy lại các tài nguyên bị rò rỉ

Nếu dự đoán của tôi là chính xác, thì maxtasksperchild sẽ được coi là giải pháp tạm thời cho các lỗi trong mã của bạn cho đến khi bạn khắc phục rò rỉ tài nguyên trong chức năng worker của mình

Xin chào, chào buổi sáng Steven,

Cảm ơn bạn rất nhiều vì đã trả lời của bạn

Hãy để tôi trả lời một số câu hỏi của bạn

  1. Hệ điều hành là Linux-64bits
  2. Tôi đang làm việc trong cụm Linux “ECGATE” có chứa một số nút. Trên thực tế, chương trình của tôi chạy trong một nút duy nhất bao gồm 2 CPU, mỗi CPU chứa 16 lõi
  3. Xin lỗi vì đã hiểu nhầm tham số “quy trình” từ lớp “Pool[]”. bạn nói đúng, nó có nghĩa là số lượng quy trình sẽ được kiểm soát bởi đối tượng Pool. Tuy nhiên, tôi muốn hiểu đầy đủ cách sử dụng tham số này. Hãy để tôi hiển thị một đoạn trích của tập lệnh Python của tôi, nơi tôi tạo một đối tượng Pool và tôi khởi chạy một số quy trình bằng cách sử dụng “pool. starmap[]” chức năng.
    Để giúp bạn hiểu rõ hơn, tôi có một mảng 3D NumPy chứa dữ liệu Lượng mưa cho toàn bộ miền của một mô hình khí tượng. Mỗi mảng 2D trong mảng 3D tương ứng với dữ liệu được liên kết với một ngày và thành viên cụ thể từ mô hình. Tôi muốn thực hiện một số phép tính liên quan đến từng điểm lưới của mô hình. Vì lý do này, tôi muốn khởi chạy các quy trình “ny * nx”. Vì vậy, tôi xác định một danh sách các đối số trong đó mỗi phần tử sẽ đồng thời là một danh sách chứa các đối số cho một quy trình cụ thể. Sau đó, tôi xác định đối tượng “Pool” [nơi tôi phải chỉ định đối số “quy trình”]. Cuối cùng, tôi gọi là “hồ bơi. starmap[]” để khởi chạy các quy trình khác nhau.

z, y, x = meteo_array. hình dạng

argument_list = []

for ny in range[y]:

   for nx in range[x]:

      argument_list.append[[meteo_array, ny, nx, cdf_mode, p_step]]

num_processes = 31

pool = mp.Pool[processes = num_processes]

cdf_array_list = pool.starmap[construct_cdf, argument_list]

Mã này hoạt động tốt và nó hoàn thành việc thực thi quy trình “nx * ny = 565 * 469 = 264985” trong 8 phút. Vấn đề là, trong định nghĩa của đối tượng Pool, tôi đã chỉ định rằng số lượng quy trình sẽ là 31

Tôi đã thực hiện một thử nghiệm nhỏ, đó là sửa đổi tham số “quy trình” để xem nó ảnh hưởng như thế nào đến thời gian thực hiện chương trình

Đây là những kết quả

quy trình = 1 ==> thời gian = 19 phút
quy trình = 2 ==> thời gian = 10 phút
quy trình = 4 ==> thời gian
processes = 8 ==> time = 2 min
processes = 16 ==> time = 4 min
processes = 31 ==> time = 8 min

Tôi nghi ngờ rằng những kết quả này có liên quan chặt chẽ với ví dụ bạn đưa ra về số lượng đầu bếp trong nhà bếp, phải không? . Tôi nghĩ rằng việc đặt "các quy trình" thành một số gần với số lượng bộ xử lý của HĐH là phản tác dụng vì chúng tôi có thể đang truy cập một số bộ xử lý [hoặc lõi] đang thực sự bận rộn với các quy trình khác [không liên quan đến việc thực thi chương trình của tôi],

Sau đó, tôi hiểu rằng đối số "quy trình" cho biết số lượng quy trình sẽ được thực thi đồng thời [hoặc tương đương, số lượng bộ xử lý được kiểm soát bởi đối tượng Pool].
Bạn có thể vui lòng cho tôi biết lời giải thích này có hợp lý không?

Cảm ơn trước,

Joan

Xin chào Joan,

Tôi thực sự thích thí nghiệm nhỏ mà bạn đã thực hiện. Bạn đã phát hiện lại sự chậm lại song song

vi. wikipedia. tổ chức

làm chậm song song

Làm chậm song song là một hiện tượng trong điện toán song song trong đó việc song song hóa thuật toán song song vượt quá một điểm nhất định khiến chương trình chạy chậm hơn [mất nhiều thời gian hơn để chạy đến khi hoàn thành]. Sự chậm lại song song thường là kết quả của tắc nghẽn truyền thông. Khi nhiều nút bộ xử lý được thêm vào, mỗi nút xử lý sẽ dành nhiều thời gian hơn cho việc giao tiếp hơn là xử lý hữu ích. Tại một số điểm, chi phí liên lạc được tạo bằng cách thêm một nút xử lý khác vượt quá

Đối số số lượng quy trình cho Nhóm cho phép bạn chỉ định có bao nhiêu quy trình công nhân được tạo và chạy; . Về nguyên tắc, bạn có thể có tối đa số lõi CPU khả dụng chạy đồng thời, nhưng trên thực tế, đó là trường hợp tốt nhất hiếm khi đạt được và nằm ngoài tầm kiểm soát của bạn

Con số thực tế sẽ phụ thuộc vào bản chất của vấn đề [có lẽ một số công nhân dành nhiều thời gian nhàn rỗi, chờ đợi dữ liệu đến với họ];

Bạn nói

“Mã này hoạt động tốt và nó hoàn thành việc thực thi quy trình “nx * ny = 565 * 469 = 264985” trong 8 phút. Vấn đề là, trong định nghĩa của đối tượng Pool, tôi đã chỉ định rằng số lượng quy trình sẽ là 31. ”

Bạn không có 264985 quy trình. Bạn có 31 quy trình, giống như bạn đã chỉ định khi tạo đối tượng Pool

Bạn có 264985 khối dữ liệu cần xử lý trong argument_list. Mỗi đoạn dữ liệu là một bộ gồm năm giá trị

[meteo_array, ny, nx, cdf_mode, p_step]

Đối tượng Pool phân chia 264985 khối dữ liệu đó giữa 31 quy trình, chạy song song. Mỗi tiến trình là một công nhân. nó có thể thực hiện một số công việc hoặc tính toán hoặc tính toán trên một đoạn dữ liệu tại một thời điểm. Bạn có 31 nhân viên, vì vậy tổng thể máy tính của bạn đang xử lý ít nhiều 31 khối dữ liệu cùng một lúc

Nó thực sự sẽ ít hơn ở mức trung bình, vì hệ điều hành vẫn sẽ cung cấp một số thời gian CPU cho hàng tá quy trình khác đang chạy trên máy của bạn. Nhưng với phép tính gần đúng đầu tiên, bạn có thể bỏ qua các quy trình khác đó và giả sử rằng 31 quy trình worker của bạn đang chạy đồng thời

Vì vậy, trung bình, mỗi worker process kết thúc việc tính toán cho 8547. 9 trong số những khối dữ liệu đó

Với một worker process duy nhất, trình thông dịch Python sẽ cần xử lý 264985 khối dữ liệu đó cùng một lúc

CPU core 1:  process chunk 1; process chunk 2; process chunk 3; ...

Với hai quy trình, bạn nhận được

CPU core 1:  process chunk 1; process chunk 3; process chunk 5; ...
CPU core 2:  process chunk 2; process chunk 4; process chunk 6; ...

Với 31 quy trình công nhân

CPU core 1: process chunk 1; process chunk 32; process chunk 63; ...
CPU core 2: process chunk 2; process chunk 33; process chunk 64; ...
CPU core 3: process chunk 3; process chunk 34; process chunk 65; ...
...
CPU core 31: process chunk 31; process chunk 62; process chunk 93; ...

Một cách ngây thơ, điều này sẽ gợi ý rằng phiên bản 31 quy trình phải nhanh hơn 31 lần so với phiên bản quy trình đơn lẻ, nhưng trên thực tế, điều đó không thực sự xảy ra. Sự khác biệt giữa lý thuyết và thực hành là

  • có hàng tá quy trình khác đang chạy trên hệ thống của bạn, bên ngoài môi trường Python;

  • cần có một số chi phí chung để quản lý tất cả các quy trình công nhân đó và càng nhiều công nhân thì càng có nhiều chi phí;

  • người ta dành nhiều thời gian hơn để chuyển dữ liệu từ quy trình Python chính đã khởi chạy công nhân, hơn là dành cho việc tính toán thực tế;

  • có thể tính toán của bạn không phù hợp lắm với xử lý song song, do đó, việc chia nó cho 31 công nhân sẽ không thể tăng tốc nó lên 31 lần

Vì vậy, bạn có bằng chứng thực tế tốt rằng đối với vấn đề cụ thể của mình, số lượng quy trình công nhân tối ưu là từ 8 đến 16 trên máy 32 lõi

Bạn nói

“Tôi nghĩ rằng việc đặt “các quy trình” thành một số gần với số lượng bộ xử lý của HĐH là phản tác dụng vì chúng tôi có thể đang truy cập một số bộ xử lý [hoặc lõi] đang thực sự bận rộn với các quy trình khác [không liên quan đến việc thực thi chương trình của tôi]

Vâng, đó là một yếu tố rất quan trọng. Hệ điều hành của bạn càng bận rộn thì thời gian CPU dành cho Nhóm quy trình công nhân của bạn càng ít

Vì bạn đang chạy Linux, nên bạn có thể xem các quy trình đang hoạt động bằng cách chạy top trong thiết bị đầu cuối, bạn sẽ thấy có bao nhiêu quy trình khác đang chạy và tổng tải là bao nhiêu

Lý tưởng nhất là tải sẽ đạt tới 32 trong khi tính toán của bạn đang chạy, điều đó có nghĩa là tất cả 32 lõi đang được sử dụng hết

Nếu tải thấp hơn đáng kể so với 32, điều đó có nghĩa là một số lõi đang ngồi xung quanh không làm gì cả

Nếu tải cao hơn 32, điều đó có nghĩa là có nhiều công việc cần phải hoàn thành hơn so với các lõi và HĐH đang tụt hậu trong việc quản lý phân bổ công việc cho các lõi và các quy trình phải chờ [có thể là một khoảng thời gian dài]. ] trước khi chúng có cơ hội chạy trên lõi

vi. wikipedia. tổ chức

Tải [máy tính]

Trong điện toán UNIX, tải hệ thống là thước đo lượng công việc tính toán mà hệ thống máy tính thực hiện. Trung bình tải đại diện cho tải hệ thống trung bình trong một khoảng thời gian. Nó thường xuất hiện dưới dạng ba số biểu thị tải hệ thống trong khoảng thời gian một, năm và mười lăm phút qua. Tất cả các hệ thống tương tự Unix và Unix tạo ra một số liệu không thứ nguyên gồm ba số "tải trung bình" trong kernel. Người dùng có thể dễ dàng truy vấn kết quả hiện tại từ một

Làm cách nào để giảm mức sử dụng CPU trong mã Python?

Nếu nó vẫn ngốn quá nhiều CPU với mã tải trọng của bạn, hãy cân nhắc tăng thời gian ngủ hơn nữa. Mặt khác, mã tải trọng có thể cần được tối ưu hóa để thực hiện lặp lại. Ví dụ: Bộ nhớ đệm có thể tăng tốc độ chạy trên dữ liệu không thay đổi

Python có thể sử dụng nhiều lõi hơn không?

Những điểm rút ra chính . Các quy trình Python thường sử dụng một luồng đơn vì GIL. Mặc dù có GIL, các thư viện thực hiện các tác vụ tính toán nặng như numpy, scipy và pytorch sử dụng triển khai dựa trên C hoàn toàn, cho phép sử dụng nhiều lõi .

Python sử dụng bao nhiêu CPU?

Trong Python, việc sử dụng một CPU là do khóa trình thông dịch toàn cầu [GIL], khóa này chỉ cho phép một luồng mang trình thông dịch Python tại bất kỳ thời điểm nào. GIL được triển khai để xử lý sự cố quản lý bộ nhớ, nhưng kết quả là Python bị hạn chế sử dụng một bộ xử lý .

Chủ Đề