2016-06-19 21 views
8

Tôi mới bắt đầu sử dụng gói CUDArt của Julia để quản lý tính toán GPU. Tôi tự hỏi làm thế nào để đảm bảo rằng nếu tôi đi để kéo dữ liệu từ gpu (ví dụ: sử dụng to_host()) mà tôi không làm như vậy trước khi tất cả các tính toán cần thiết đã được thực hiện trên nó.Làm thế nào để đồng bộ hóa với Julia CUDArt?

Thông qua một số thử nghiệm, có vẻ như to_host(CudaArray) sẽ bị trễ trong khi CudaArray cụ thể đang được cập nhật. Vì vậy, có lẽ chỉ cần sử dụng này là đủ để đảm bảo an toàn? Nhưng có vẻ như một chút chancy.

Hiện tại, tôi đang sử dụng chức năng launch() để chạy hạt nhân của tôi, như được mô tả trong gói documentation.

Tài liệu CUDArt cung cấp ví dụ sử dụng macro @sync của Julia, có vẻ như nó có thể đáng yêu. Nhưng với mục đích của @sync Tôi đã làm xong với "công việc" của mình và sẵn sàng chuyển ngay khi hạt nhân được khởi chạy với launch(), chứ không phải khi nó kết thúc. Theo như tôi hiểu hoạt động của launch() - không có cách nào để thay đổi tính năng này (ví dụ: để làm cho nó chờ để nhận được đầu ra của hàm nó "khởi chạy").

Làm cách nào để tôi có thể thực hiện đồng bộ hóa như vậy?

Trả lời

1

Tôi nghĩ rằng cách kinh điển hơn là để thực hiện một dòng cho từng thiết bị:

streams = [(device(dev); Stream()) for dev in devlist]

và sau đó bên trong khối @async, sau khi bạn nói với nó để làm các phép tính, bạn sử dụng wait(stream) chức năng để yêu cầu nó đợi luồng đó kết thúc tính toán của nó. Xem ví dụ về Luồng trong README.

+0

Điểm tốt. Tôi nghĩ 'device_synchronize' vẫn có thể hữu ích trong một số cài đặt. 1. Bạn có thể sử dụng nó cùng với các chức năng khác, chẳng hạn như các hàm từ CUBLAS, CUSPARSE, v.v. không lấy luồng làm đối số. Ngoài ra, nếu bạn chỉ làm việc với một GPU, bạn có thể thậm chí không cần luồng, và vì vậy 'device_synchronize' có thể dẫn đến một ứng dụng đơn giản hơn một chút. –

10

Ok, vì vậy, không có nhiều tài liệu về gói CUDArt, nhưng tôi đã xem mã nguồn và tôi nghĩ nó có vẻ đơn giản về cách thực hiện điều này. Đặc biệt, có vẻ như có chức năng device_synchronize() sẽ chặn cho đến khi tất cả công việc trên thiết bị đang hoạt động đã hoàn tất. Do đó, những điều sau đây có vẻ như hoạt động:

using CUDArt 
md = CuModule("/path/to/module.ptx",false) 
MyFunc = CuFunction(md,"MyFunc") 
GridDim = 2*2496 
BlockDim = 64 
launch(MyFunc, GridDim, BlockDim, (arg1, arg2, ...)); 
device_synchronize() 
res = to_host(arg2) 

Tôi rất muốn nghe từ bất kỳ ai có chuyên môn hơn mặc dù có bất kỳ điều gì cần lưu ý ở đây.

+7

Chỉ cần cảnh báo: các chức năng không có giấy tờ có thể ở đó để sử dụng nội bộ (do đó thiếu tài liệu). Rõ ràng đây không phải lúc nào cũng như vậy, nhưng, nếu bạn sử dụng các chức năng này, bạn có thể đang gặp khó khăn khi nâng cấp lên phiên bản tiếp theo. Chủ sở hữu gói và thư viện có xu hướng cảm thấy thoải mái hơn về việc sửa đổi hoặc loại bỏ hoàn toàn nhiều tính năng không có giấy tờ, ngay cả giữa các phiên bản nhỏ. Tiến hành thận trọng và đảm bảo viết các bài kiểm tra hồi quy. – JDB

Các vấn đề liên quan