Sử dụng các luồng khác nhau cho hạt nhân CUDA làm cho việc thực hiện hạt nhân đồng thời có thể. Do đó, n
hạt nhân trên n
luồng về mặt lý thuyết có thể chạy đồng thời nếu chúng phù hợp với phần cứng, phải không?Thực hiện hạt nhân đồng thời CUDA với nhiều hạt nhân trên mỗi luồng
Hiện tôi đang gặp sự cố sau: Không có n
hạt riêng biệt nhưng n*m
trong đó m
nhân cần được thực thi theo thứ tự. Ví dụ n=2
và m=3
sẽ dẫn đến các chương trình thực hiện sau đây với suối:
Stream 1: <<<Kernel 0.1>>> <<<Kernel 1.1>>> <<<Kernel 2.1>>>
Stream 2: <<<Kernel 0.2>>> <<<Kernel 1.2>>> <<<Kernel 2.2>>>
giả ngây thơ của tôi là những hạt nhân x.0 và y.1 nên thực hiện đồng thời (từ một quan điểm lý thuyết của xem) hoặc ít nhất không liên tiếp (từ quan điểm thực tế). Nhưng các phép đo của tôi cho tôi thấy rằng đây không phải là trường hợp và có vẻ như việc thực hiện liên tiếp được thực hiện (i. E. K0.0, K1.0, K2.0, K0.1, K1.1, K2.1). Các hạt nhân chính nó là rất nhỏ, do đó, thực hiện đồng thời không phải là một vấn đề.
Bây giờ cách tiếp cận của tôi sẽ là thực hiện một loại điều phối để đảm bảo rằng các hạt nhân được xếp hàng đợi theo kiểu xen kẽ vào bộ lập lịch trên GPU. Nhưng khi giao dịch với một số lượng lớn các luồng/hạt nhân, điều này có thể gây hại nhiều hơn lợi ích.
Được rồi, đến thẳng điểm: Cách tiếp cận thích hợp (hoặc ít nhất là khác) để giải quyết tình huống này là gì?
Chỉnh sửa: Các phép đo được thực hiện bằng cách sử dụng các sự kiện CUDA. Tôi đã đo thời gian cần thiết để giải quyết hoàn toàn tính toán, i. e. GPU phải tính tất cả các hạt nhân n * m
. Giả thiết là: Trên thực thi hạt nhân đồng thời hoàn toàn, thời gian thực hiện là khoảng thời gian (lý tưởng) 1/n
thời gian cần thiết để thực thi tất cả các hạt theo thứ tự, theo đó phải có khả năng thực hiện đồng thời hai hoặc nhiều hạt nhân. Tôi đảm bảo điều này bằng cách chỉ sử dụng hai luồng riêng biệt ngay bây giờ.
Tôi có thể đo lường sự khác biệt rõ ràng về thời gian thực hiện giữa việc sử dụng các luồng như mô tả và cử các hạt nhân xen kẽ, i. E .:
Loop: i = 0 to m
EnqueueKernel(Kernel i.1, Stream 1)
EnqueueKernel(Kernel i.2, Stream 2)
so
Loop: i = 1 to n
Loop: j = 0 to m
EnqueueKernel(Kernel j.i, Stream i)
Các dẫn sau để một thời gian chạy lâu hơn.
Chỉnh sửa # 2: Đã thay đổi số Luồng để bắt đầu bằng 1 (thay vì 0, xem nhận xét bên dưới).
Chỉnh sửa # 3: Phần cứng là một NVIDIA Tesla M2090 (tức là Fermi, tính toán khả năng 2.0)
Bạn có thể cần sử dụng một số nguyên tắc đồng bộ hóa luồng để thực thi thứ tự thực hiện mà bạn cần. Nhưng bạn có thể mở rộng một chút về cách bạn thực hiện các phép đo trong câu hỏi của mình và bạn cũng có thể xác nhận rằng khi bạn viết "Luồng 0", nghĩa là bạn không có nghĩa là luồng CUDA 0? – talonmies
Tôi đã làm rõ phép đo (ít nhất tôi hy vọng như vậy). Với các luồng, tôi có nghĩa là các thể hiện của 'cudaStream_t' như được mô tả trong [Hướng dẫn lập trình CUDA C] (http://developer.download.nvidia.com/compute/DevZone/docs/html/C/doc/CUDA_C_Programming_Guide.pdf), phần 3.2.5 (Thực thi đồng thời không đồng bộ). –
Có lẽ bạn đã hiểu lầm những gì tôi đã hỏi - ý tôi là một trong các luồng suối của bạn là CUDA 0, vì luồng 0 (luồng mặc định) là đồng bộ. – talonmies