Tôi muốn song song hóa một vòng lặp while trong đoạn mã sau:
làm việc <- chức năng (n) {
# Thực hiện một số công việc chuyên sâu (ví dụ: khám phá biểu đồ bắt đầu từ n).
# Sau này, chúng ta không cần thực thi công việc() trên các nút trong quá trình loại trừ.
# (ví dụ: loại trừ có thể là các nút được khám phá/tiếp cận từ n)
# n chỉ là một ví dụ. loại trừ có thể là một tập hợp lớn.
Sys.sleep(2)
loại trừ <- c(n, sample(nodes, rbinom(1, length(nodes), 0.5)))
trả lại (loại trừ)
}
nút <- 1:1e3
#Thứ tự thực hiện không quan trọng
nút <- mẫu(nút)
#song song hóa vòng lặp này
while(độ dài(nút) > 0) {
n <- nút [1]
loại trừ <- công việc (n)
nút <- setdiff(nút, loại trừ)
}
công việc()
Bạn có thể thực thi trên các nút bị loại trừ nhưng chúng tôi muốn giảm thiểu các trường hợp như vậy. Mục tiêu của vòng lặp while ở trên là chạy Work() càng ít càng tốt
Đây không phải là tính toán song song đáng xấu hổ nên tôi không biết cách sử dụng parLaply
trực tiếp. Có thể sử dụng các khung công tác chủ-nô lệ, nhưng tôi không biết bất kỳ khung nào cho lập trình đa lõi (trên Windows).
Như một ví dụ cụ thể, bạn có thể nghĩ đếncông việc(n)
作为đồ thị_khám phá(n)
(Hàm tìm kết nối tới n
tất cả các nút) và loại trừ
như các nút trong các thành phần liên thông của n. Mục tiêu cuối cùng là tìm một nút từ mỗi thành phần được kết nối. bạn muốn chạy đồ thị_khám phá(n)
Càng ít càng tốt, vì đây là một hoạt động tốn kém.
Mihir,
Đây là một giải pháp được đề xuất.
Lời nói đầu:
Vấn đề cốt lõi ở đây (theo như tôi có thể nói) là ở chỗ công việc()
Mở khóa vòng lặp while khi thực hiện thao tác bẻ số. Về cơ bản, bạn muốn vòng lặp không bị chặn miễn là tài nguyên vẫn còn sẵn để bắt đầu thêm công việc()
gọi và xử lý. Được rồi phải làm gì? Vâng, đề nghị của tôi là bạn sử dụng tương laiCái túi.
Ví dụ dưới đây về cơ bản tạo một cuộc gọi mới cho mỗi cuộc gọi công việc()
xử lý cuộc gọi. Tuy nhiên, cuộc gọi sẽ không chặn vòng lặp while trừ khi tất cả các tiến trình công nhân được chỉ định đều bận. Bạn có thể thấy điều này bởi vì mỗi công việc()
Tất cả các cuộc gọi đều có ID tiến trình khác nhau, như được hiển thị trong đầu ra thời gian chạy.
Vì vậy, mọi công việc()
Tất cả đều chạy độc lập. Để hoàn thành, chúng tôi giải quyết tất cả các tương lai và trả về kết quả cuối cùng.
kết quả:
- Thời gian chạy tuần tự:Đã trôi qua 20,61 giây
- Khi chạy song song:Đã trôi qua 8,22 giây
Tôi hy vọng điều này chỉ cho bạn đi đúng hướng.
cảnh báo:Bạn phải duyệt qua tất cả các nút, nhưng nó sẽ cải thiện thời gian chạy.
Cài đặt máy:
Phiên bản R 3.4.1 (2017-06-30)
Nền tảng: x86_64-w64-mingw32/x64 (64-bit)
Chạy trên: Windows >= 8 x64 (bản dựng 9200)
[Windows 10, Xeon 8 nhân, RAM 64Gb]
Ví dụ mã song song:
# Kiểm tra, cài đặt và tải các gói cần thiết.
gói bắt buộc <-
c("tictoc", "listenv", "tương lai")
ipak <- hàm(pkg) {
new.pkg <- pkg[!(pkg %in% đã cài đặt.packages()[, "Gói"])]
if (độ dài (new.pkg))
install.packages(new.pkg, dependency = TRUE)
sapply(pkg, require, character.only = TRUE)
}
ipak (Gói bắt buộc)
làm việc <- chức năng (n) {
# Thực hiện một số công việc chuyên sâu (ví dụ: khám phá biểu đồ bắt đầu từ n).
# Sau này, chúng ta không cần thực thi công việc() trên các nút bị loại trừ.
# (ví dụ: loại trừ có thể là các nút được khám phá/tiếp cận từ n)
# n chỉ là một ví dụ. loại trừ có thể là một tập hợp lớn.
Sys.sleep(2) # sample(.5:5))
loại trừ <- n
trả lại (loại trừ)
}
kế hoạch (đa tiến trình, công nhân = 4L)
#kế hoạch(tuần tự)
nútĐồ thị <- 1:10
nútGraph <- mẫu(nodesGraph)
nútCount <- chiều dài (nodesGraph)
resultsList <- listenv()
tic()
trong khi ( nútCount > 0 ) {
n <- nodeGraph[[nodesCount]]
## Điều này được đánh giá song song và sẽ chỉ chặn
## nếu tất cả công nhân đều bận.
resultsList[[nodesCount]] %<-% {
danh sách (loại trừ = công việc (n),
lặp = chiều dài (nodesGraph),
pid = Sys.getpid())
}
nútGraph <- setdiff(nodesGraph, nodeGraph[[nodesCount]] )
cat("nodesGraph",nodesGraph,"\n")
cat("nodesCount",nodesCount,"\n")
nútCount = nútCount - 1
}
toc()
## Giải quyết tất cả các tương lai (chặn nếu chưa hoàn thành)
resultsList <- as.list(resultsList)
str(danh sách kết quả)
Đầu ra khi chạy song song:
> nguồn('/dev/stackoverflow/47230384/47230384v5.R')
nútĐồ thị 2 5 8 4 6 10 7 1 9
nútĐếm 10
nútĐồ thị 2 5 8 4 6 10 7 1
nútĐếm 9
nútĐồ thị 2 5 8 4 6 10 7
nútĐếm 8
nútĐồ thị 2 5 8 4 6 10
nútĐếm 7
nútĐồ thị 2 5 8 4 6
nútĐếm 6
nútĐồ thị 2 5 8 4
nútĐếm 5
nútĐồ thị 2 5 8
nútĐếm 4
nútĐồ thị 2 5
nútĐếm 3
nútĐồ thị 2
nútĐếm 2
nútĐồ thị
nútĐếm 1
8,22 giây trôi qua
Danh sách 10
$ :Danh sách 3
..$ loại trừ: int 2
..$ lần lặp: int 1
..$ pid : int 10692
$ :Danh sách 3
..$ loại trừ: int 5
..$ lần lặp: int 2
..$ pid : int 2032
$ :Danh sách 3
..$ loại trừ: int 8
..$ lần lặp: int 3
..$ pid : int 16356
$ :Danh sách 3
..$ loại trừ: int 4
..$ lần lặp: int 4
..$ pid : int 7756
$ :Danh sách 3
..$ loại trừ: int 6
..$ lần lặp: int 5
..$ pid : int 10692
$ :Danh sách 3
..$ loại trừ: int 10
..$ lần lặp: int 6
..$ pid : int 2032
$ :Danh sách 3
..$ loại trừ: int 7
..$ lần lặp: int 7
..$ pid : int 16356
$ :Danh sách 3
..$ loại trừ : int 1
..$ lần lặp: int 8
..$ pid : int 7756
$ :Danh sách 3
..$ loại trừ: int 9
..$ lần lặp: int 9
..$ pid : int 10692
$ :Danh sách 3
..$ loại trừ : int 3
..$ lần lặp: int 10
..$ pid : int 2032
Đầu ra khi chạy tuần tự
> nguồn('/dev/stackoverflow/47230384/47230384v5.R')
nútĐồ thị 6 2 1 9 4 8 10 7 3
nútĐếm 10
nútĐồ thị 6 2 1 9 4 8 10 7
nútĐếm 9
nútĐồ thị 6 2 1 9 4 8 10
nútĐếm 8
nútĐồ thị 6 2 1 9 4 8
nútĐếm 7
nútĐồ thị 6 2 1 9 4
nútĐếm 6
nútĐồ thị 6 2 1 9
nútĐếm 5
nútĐồ thị 6 2 1
nútĐếm 4
nútĐồ thị 6 2
nútĐếm 3
nútĐồ thị 6
nútĐếm 2
nútĐồ thị
nútĐếm 1
20,61 giây trôi qua
Danh sách 10
$ :Danh sách 3
..$ loại trừ: int 6
..$ lần lặp: int 1
..$ pid : int 12484
$ :Danh sách 3
..$ loại trừ: int 2
..$ lần lặp: int 2
..$ pid : int 12484
$ :Danh sách 3
..$ loại trừ : int 1
..$ lần lặp: int 3
..$ pid : int 12484
$ :Danh sách 3
..$ loại trừ: int 9
..$ lần lặp: int 4
..$ pid : int 12484
$ :Danh sách 3
..$ loại trừ: int 4
..$ lần lặp: int 5
..$ pid : int 12484
$ :Danh sách 3
..$ loại trừ: int 8
..$ lần lặp: int 6
..$ pid : int 12484
$ :Danh sách 3
..$ loại trừ: int 10
..$ lần lặp: int 7
..$ pid : int 12484
$ :Danh sách 3
..$ loại trừ: int 7
..$ lần lặp: int 8
..$ pid : int 12484
$ :Danh sách 3
..$ loại trừ : int 3
..$ lần lặp: int 9
..$ pid : int 12484
$ :Danh sách 3
..$ loại trừ: int 5
..$ lần lặp: int 10
..$ pid : int 12484
Tôi là một lập trình viên xuất sắc, rất giỏi!