Gói doParallel
sẽ tự động xuất biến cho công nhân được tham chiếu trong vòng foreach
. Nếu bạn không muốn làm điều đó, bạn có thể sử dụng tùy chọn foreach
".không xuất hiện" để ngăn không cho tự động xuất các biến cụ thể. Nhưng nếu tôi hiểu bạn một cách chính xác, vấn đề của bạn là R sau đó nhân bản một số biến đó, mà thậm chí còn nhiều vấn đề hơn bình thường vì nó đang xảy ra trong nhiều tiến trình trên một máy.
Không có cách nào để khai báo biến để R sẽ không bao giờ sao chép biến đó. Bạn cần phải thay thế các biến vấn đề với các đối tượng từ một gói như bigmemory
sao cho các bản sao không bao giờ được thực hiện hoặc bạn có thể thử sửa đổi mã theo cách sao cho không kích hoạt tính năng sao chép. Bạn có thể sử dụng chức năng tracemem
để giúp bạn, vì nó sẽ in một tin nhắn bất cứ khi nào đối tượng đó được nhân bản.
Tuy nhiên, bạn có thể tránh được sự cố bằng cách giảm dữ liệu cần thiết cho công nhân. Điều đó làm giảm lượng dữ liệu cần phải được sao chép vào từng công nhân, cũng như giảm lượng bộ nhớ của chúng.
Dưới đây là một ví dụ điển hình của việc cho người lao động dữ liệu hơn là họ cần:
x <- matrix(1:100, 10)
foreach(i=1:10, .combine='c') %dopar% {
mean(x[,i])
}
Kể từ khi ma trận x
được tham chiếu trong foreach
vòng lặp, nó sẽ được tự động xuất khẩu cho mỗi người lao động, thậm chí mặc dù mỗi công nhân chỉ cần một tập con của các cột. Giải pháp đơn giản nhất là để lặp qua các cột thực tế của ma trận chứ không phải qua các chỉ số cột:
foreach(xc=x, .combine='c') %dopar% {
mean(xc)
}
Không chỉ là ít dữ liệu chuyển giao cho người lao động, nhưng mỗi công nhân chỉ thực sự cần phải có một cột trong bộ nhớ tại một thời điểm, làm giảm đáng kể dung lượng bộ nhớ của nó đối với các ma trận lớn. Các vector xc
vẫn có thể kết thúc được nhân đôi, nhưng nó không làm tổn thương gần như nhiều vì nó là nhỏ hơn nhiều so với x
. Lưu ý rằng kỹ thuật này chỉ giúp khi doParallel
sử dụng các chức năng "có nguồn gốc từ tuyết", chẳng hạn như parLapply
và clusterApplyLB
, chứ không phải khi sử dụng mclapply
. Sử dụng kỹ thuật này có thể làm cho vòng lặp chậm hơn một chút khi sử dụng mclapply
vì tất cả các nhân viên đều nhận được ma trận x
miễn phí, vậy tại sao lại chuyển xung quanh các cột khi công nhân đã có toàn bộ ma trận? Tuy nhiên, trên Windows, doParallel
không thể sử dụng mclapply
, vì vậy kỹ thuật này rất quan trọng.
Điều quan trọng là phải suy nghĩ về những dữ liệu thực sự cần thiết cho công nhân để thực hiện công việc của họ và cố gắng giảm nó nếu có thể. Đôi khi bạn có thể làm điều đó bằng cách sử dụng các trình vòng lặp đặc biệt, hoặc từ các gói iterators
hoặc itertools
, nhưng bạn cũng có thể thực hiện điều đó bằng cách thay đổi thuật toán của mình.
Tôi về cơ bản đã hỏi cùng một câu hỏi trong một thời gian trước (http://stackoverflow.com/questions/6251662/writing-to-global-environment-when-running-in-parallel), nhưng mọi thứ có thể đã thay đổi ở mức trung bình thời gian? –
Cảm ơn Roman, tôi cũng bị mắc kẹt trên Windows; hy vọng ai đó biết cách thoát ra ngoài. Tôi không cần bình chọn/thay đổi biến lớn (mạng) vì tôi chỉ đọc nó để tính toán điểm số trung tâm .. – user2272413
Tùy thuộc vào dữ liệu bạn muốn chia sẻ có thể được biểu diễn bằng ma trận hay không, gói 'bigmemory' có thể cho phép những gì bạn đang theo dõi. Gói đó cho phép truy cập chia sẻ để xử lý song song, ngay cả trên các cửa sổ. Tuy nhiên, nếu đối tượng chia sẻ không thể được biểu diễn bằng ma trận, bạn sẽ không đi xa trên con đường đó. – BenBarnes