2011-09-23 27 views
6

Tôi muốn hiểu bối cảnh cuda được tạo ra và liên kết với hạt nhân trong các ứng dụng API runtime cuda như thế nào?tạo ngữ cảnh cuda và liên kết tài nguyên trong các ứng dụng API runtime

Tôi biết nó được thực hiện dưới mui xe của API trình điều khiển. Nhưng tôi muốn hiểu thời gian của sự sáng tạo.

Để bắt đầu, tôi biết cudaRegisterFatBinary là cuộc gọi cuda api đầu tiên được thực hiện và nó đăng ký một tệp fatbin với thời gian chạy. Tiếp theo là một số API đăng ký hàm cuda gọi cuModuleLoad trong lớp trình điều khiển. Nhưng sau đó nếu ứng dụng API thời gian chạy Cuda của tôi gọi cudaMalloc thì con trỏ được cung cấp cho hàm này được liên kết với ngữ cảnh như thế nào, mà tôi tin rằng lẽ ra phải được tạo trước đó. Làm thế nào để có được một xử lý cho bối cảnh đã được tạo ra này và kết hợp các cuộc gọi API thời gian chạy trong tương lai với nó? Hãy làm sáng tỏ các hoạt động bên trong.

Để trích dẫn tài liệu của NVIDIA về vấn đề này

CUDA Runtime API cuộc gọi hoạt động trên CUDA CUcontext điều khiển API mà được ràng buộc với chủ đề máy chủ hiện tại.

Nếu có tồn tại không có CUDA driver API CUcontext ràng buộc với thread hiện hành tại thời điểm một cuộc gọi CUDA Runtime API mà đòi hỏi một CUcontext thì CUDA Runtime ngầm sẽ tạo ra một CUcontext mới trước khi thực hiện cuộc gọi.

Nếu CUDA Runtime tạo ra một CUcontext thì CUcontext sẽ tạo bằng cách sử dụng các thông số quy định của CUDA Runtime API chức năng cudaSetDevice, cudaSetValidDevices, cudaSetDeviceFlags, cudaGLSetGLDevice, cudaD3D9SetDirect3DDevice, cudaD3D10SetDirect3DDevice, và cudaD3D11SetDirect3DDevice. Lưu ý rằng các chức năng này sẽ không thành công với cudaErrorSetOnActiveProcess nếu chúng là được gọi khi CUcontext bị ràng buộc với luồng lưu trữ hiện tại.

Tuổi thọ của CUcontext được quản lý bằng cơ chế tính tham chiếu . Số lượng tham chiếu của CUcontext ban đầu được đặt thành 0, và được tăng lên bởi cuCtxAttach và được giảm dần bởi cuCtxDetach.

Nếu CUcontext được tạo bởi Thời gian chạy CUDA, thời gian chạy CUDA sẽ giảm số lượng tham chiếu của CUcontext đó trong hàm cudaThreadExit. Nếu CUcontext được tạo bởi API trình điều khiển CUDA (hoặc được tạo bởi một cá thể riêng biệt của thư viện API thời gian chạy CUDA), thì Thời gian chạy CUDA sẽ không tăng hoặc giảm tham chiếu số của CUcontext đó.

Tất cả trạng thái API thời gian chạy CUDA (ví dụ: địa chỉ biến toàn cầu và giá trị ) truyền đi với CUcontext cơ bản của nó. Đặc biệt, nếu CUcontext được di chuyển từ một chủ đề này sang chuỗi khác (sử dụng cuCtxPopCurrent và cuCtxPushCurrent) thì tất cả trạng thái API thời gian chạy CUDA cũng sẽ chuyển sang chuỗi đó.

Nhưng điều tôi không hiểu là thời gian chạy cuda tạo ngữ cảnh như thế nào? những gì các cuộc gọi API được sử dụng cho điều này? Liệu trình biên dịch nvcc chèn một số cuộc gọi API để làm điều này tại thời gian biên dịch hoặc được thực hiện hoàn toàn trong thời gian chạy? Nếu điều gì là đúng thì API thời gian chạy nào được sử dụng cho quản lý ngữ cảnh này? Nó sau đó là đúng như thế nào chính xác là nó được thực hiện?

Nếu ngữ cảnh được liên kết với chuỗi chủ, cách chúng tôi có quyền truy cập vào ngữ cảnh này? Nó có tự động liên kết với tất cả các biến và tham chiếu con trỏ được xử lý bởi luồng không?

làm thế nào cuối cùng là tải mô-đun được thực hiện trong ngữ cảnh?

Trả lời

3

Thời gian chạy CUDA duy trì danh sách mô-đun toàn cục để tải và thêm vào danh sách đó mỗi khi có tệp DLL hoặc .so sử dụng thời gian chạy CUDA được tải vào quy trình. Nhưng các mô-đun không thực sự được tải cho đến khi thiết bị được tạo.

Tạo và khởi tạo ngữ cảnh được thực hiện "chậm" theo thời gian chạy CUDA - mỗi khi bạn gọi một hàm như cudaMemcpy(), nó kiểm tra xem liệu CUDA đã được khởi tạo hay chưa, và nếu không, nó tạo ra ngữ cảnh (trên thiết bị được xác định trước bởi cudaSetDevice() hoặc thiết bị mặc định nếu cudaSetDevice() chưa bao giờ được gọi) và tải tất cả các mô-đun. Ngữ cảnh được liên kết với luồng CPU đó từ đó trở đi, cho đến khi nó được thay đổi bởi cudaSetDevice().

Bạn có thể sử dụng chức năng quản lý ngữ cảnh/chuỗi từ API trình điều khiển, chẳng hạn như cuCtxPopCurrent()/cuCtxPushCurrent(), để sử dụng ngữ cảnh từ một chuỗi khác.

Bạn có thể gọi cudaFree (0); để ép buộc sự khởi tạo lười biếng này xảy ra.

Tôi khuyên bạn nên làm như vậy tại thời điểm khởi tạo ứng dụng, để tránh điều kiện chủng tộc và hành vi không xác định. Hãy tiếp tục và liệt kê và khởi tạo thiết bị càng sớm càng tốt trong ứng dụng của bạn; một khi đã xong, trong CUDA 4.0 bạn có thể gọi cudaSetDevice() từ bất kỳ chuỗi CPU nào và nó sẽ chọn ngữ cảnh tương ứng được tạo bởi mã khởi tạo của bạn.

+0

Tôi đã thử sử dụng cudaFree (0). Nhưng tôi vẫn không hiểu được ngữ cảnh. CuCtxPop trả về một giá trị rỗng. Tại sao nó như vậy? – ash

+0

Bạn chắc chắn nên có một ngữ cảnh hiện tại sau một cudaFree thành công (0). Bạn có kiểm tra giá trị trả lại không? – ArchaeaSoftware

+0

Vì vậy, sau khi xem xét vấn đề tôi thấy rằng CudaFree (0) đang cho tôi một lỗi xử lý tài nguyên không hợp lệ. Bạn có ý kiến ​​gì không? – ash

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