Khi bạn viết A | B
, cả hai quá trình đã chạy song song. Nếu bạn thấy chúng chỉ sử dụng một lõi, thì đó có thể là do cài đặt mối quan hệ CPU (có lẽ có một số công cụ để tạo ra một quy trình có ái lực khác nhau) hoặc vì một quy trình không đủ để giữ toàn bộ lõi và hệ thống " thích "không phổ biến điện toán.
Để chạy một số B với một A, bạn cần một công cụ như split
với --filter
tùy chọn:
A | split [OPTIONS] --filter="B"
Tuy nhiên, điều này có khả năng làm xáo trộn thứ tự các dòng trong đầu ra, bởi vì các công việc B sẽ không chạy cùng tốc độ. Nếu đây là một vấn đề, bạn có thể cần phải chuyển hướng đầu ra B i-th sang một tệp trung gian và gắn chúng lại với nhau ở cuối bằng cách sử dụng cat
. Điều này, đến lượt nó, có thể yêu cầu một không gian đĩa đáng kể.
Các tùy chọn khác tồn tại (ví dụ bạn có thể giới hạn mỗi thể hiện của B để một đầu ra dòng đệm đơn, chờ đợi cho đến khi toàn bộ "vòng" của B đã hoàn tất, chạy tương đương với một giảm để split
's bản đồ , và cat
đầu ra tạm thời với nhau), với mức độ hiệu quả khác nhau. Tùy chọn 'round' vừa được mô tả chẳng hạn sẽ đợi trường hợp B chậm nhất kết thúc, do đó, nó sẽ phụ thuộc rất nhiều vào bộ đệm có sẵn cho B; [m]buffer
có thể giúp hoặc có thể không, tùy thuộc vào hoạt động là gì.
Ví dụ
Tạo 1000 số đầu tiên và đếm các dòng song song:
seq 1 1000 | split -n r/10 -u --filter="wc -l"
100
100
100
100
100
100
100
100
100
100
Nếu chúng ta "đánh dấu" các dòng, chúng ta sẽ thấy rằng mỗi dòng đầu tiên được gửi đến quy trình số 1, mỗi dòng thứ năm để xử lý số 5, v.v. Hơn nữa, trong thời gian cần thiết split
để sinh ra quá trình thứ hai, lần đầu tiên đã là một cách tốt để đạt được hạn ngạch của nó:
seq 1 1000 | split -n r/10 -u --filter="sed -e 's/^/$RANDOM - /g'" | head -n 10
19190 - 1
19190 - 11
19190 - 21
19190 - 31
19190 - 41
19190 - 51
19190 - 61
19190 - 71
19190 - 81
Khi thực hiện trên một máy 2 lõi, seq
, split
và wc
quá trình chia sẻ các lõi; nhưng nhìn kỹ hơn, hệ thống để lại hai tiến trình đầu tiên trên CPU0 và chia CPU1 cho các tiến trình worker:
%Cpu0 : 47.2 us, 13.7 sy, 0.0 ni, 38.1 id, 1.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 15.8 us, 82.9 sy, 0.0 ni, 1.0 id, 0.0 wa, 0.3 hi, 0.0 si, 0.0 st
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
5314 lserni 20 0 4516 568 476 R 23.9 0.0 0:03.30 seq
5315 lserni 20 0 4580 720 608 R 52.5 0.0 0:07.32 split
5317 lserni 20 0 4520 576 484 S 13.3 0.0 0:01.86 wc
5318 lserni 20 0 4520 572 484 S 14.0 0.0 0:01.88 wc
5319 lserni 20 0 4520 576 484 S 13.6 0.0 0:01.88 wc
5320 lserni 20 0 4520 576 484 S 13.3 0.0 0:01.85 wc
5321 lserni 20 0 4520 572 484 S 13.3 0.0 0:01.84 wc
5322 lserni 20 0 4520 576 484 S 13.3 0.0 0:01.86 wc
5323 lserni 20 0 4520 576 484 S 13.3 0.0 0:01.86 wc
5324 lserni 20 0 4520 576 484 S 13.3 0.0 0:01.87 wc
Đặc biệt lưu ý rằng đó split
là ăn một lượng đáng kể CPU. Điều này sẽ giảm tỷ lệ thuận với nhu cầu của A; tức là, nếu A là một quá trình nặng hơn seq
, thì chi phí tương đối split
sẽ giảm. Nhưng nếu A là một quá trình rất nhẹ và B khá nhanh (do đó bạn không cần nhiều hơn 2-3 B để theo kịp A), thì song song với split
(hoặc các đường ống nói chung) có thể không có giá trị.
A | B | C
song song như trong các quy trình riêng biệt, do tính chất của đường ống (B phải chờ đầu ra của A, C phải chờ đầu ra của B), nó vẫn có thể là tuyến tính trong một số trường hợp. Nó hoàn toàn phụ thuộc vào loại sản phẩm họ sản xuất. Không có nhiều trường hợp chạy nhiềuB
sẽ giúp ích nhiều, hoàn toàn có thể ví dụ wc song song chậm hơn bình thườngwc
vì việc chia tách có thể chiếm nhiều tài nguyên hơn so với đếm các dòng thông thường. Sử dụng cẩn thận.