Tôi sẽ cố gắng tóm tắt những kinh nghiệm của tôi có được trong quá trình phát triển ViennaCL, nơi chúng tôi có các phụ trợ CUDA và OpenCL với hầu hết các bản dịch 1: 1 của rất nhiều hạt nhân tính toán. Từ câu hỏi của bạn, tôi cũng sẽ cho rằng chúng ta chủ yếu lấy GPU ở đây.
Hiệu suất di động.Trước hết, không có thứ gọi là hạt nhân hiệu năng theo nghĩa là bạn viết kernel một lần và nó sẽ chạy hiệu quả trên mọi phần cứng. Không phải trong OpenCL, nơi nó rõ ràng hơn do phạm vi phần cứng được hỗ trợ rộng hơn, nhưng cũng không có trong CUDA. Trong CUDA thì ít rõ ràng hơn vì phạm vi phần cứng được hỗ trợ nhỏ hơn, nhưng ngay cả ở đây chúng ta phải phân biệt ít nhất ba kiến trúc phần cứng (tiền Fermi, Fermi, Kepler). Những biến động hiệu suất này có thể dễ dàng dẫn đến một biến thể hiệu suất 20 phần trăm tùy thuộc vào cách bạn phối hợp các luồng và kích thước nhóm công việc bạn chọn, ngay cả khi kernel đơn giản như một bản sao bộ đệm. Có lẽ cũng đáng nói rằng trên các GPU trước Fermi và Fermi, có thể viết các hạt nhân ma trận nhanh ma trận nhanh trực tiếp trong CUDA, trong khi đối với các GPU Kepler mới nhất, có vẻ như người ta phải sử dụng ngôn ngữ lắp ráp giả PTX để tiến gần đến hiệu suất của CUBLAS. Do đó, ngay cả một ngôn ngữ do nhà cung cấp kiểm soát như CUDA dường như có vấn đề để theo kịp tốc độ phát triển phần cứng. Hơn nữa, tất cả mã CUDA được biên dịch tĩnh khi bạn chạy nvcc, phần nào yêu cầu một hành động cân bằng thông qua cờ -arch, trong khi các hạt nhân OpenCL được biên dịch trong thời gian chạy từ trình biên dịch đúng lúc, do đó, về nguyên tắc bạn có thể điều chỉnh các hạt nhân xuống các chi tiết cụ thể của một thiết bị tính toán cụ thể. Tuy nhiên, thứ hai là khá liên quan và thường chỉ trở thành một lựa chọn rất hấp dẫn khi mã của bạn đáo hạn và khi kinh nghiệm của bạn tích lũy. Cái giá phải trả là thời gian O (1) cần thiết cho việc biên dịch chỉ trong thời gian, đây có thể là một vấn đề trong một số tình huống. MởCL 2.
Gỡ lỗi và hồ sơ. Các công cụ gỡ lỗi và lược tả CUDA là công cụ tốt nhất có sẵn cho GPGPU. Các công cụ của AMD cũng không tệ, nhưng chúng không bao gồm các loại đá quý như cuda-gdb hoặc cuda-memcheck. Ngoài ra, ngày nay NVIDIA vẫn cung cấp trình điều khiển và SDK mạnh mẽ nhất cho GPGPU, việc đóng băng hệ thống do hạt nhân lỗi thực sự là ngoại lệ, không phải là quy tắc, cả với OpenCL và CUDA. Vì những lý do có lẽ tôi không cần phải giải thích ở đây, NVIDIA không còn cung cấp gỡ lỗi và định hình cho OpenCL với CUDA 5.0 trở lên.
Khả năng tiếp cận và thuận tiện. Dễ dàng hơn nhiều để có được các mã CUDA đầu tiên và chạy, đặc biệt vì mã CUDA tích hợp khá độc đáo với mã máy chủ. (Tôi sẽ thảo luận về giá phải trả sau.) Có rất nhiều hướng dẫn trên mạng cũng như hướng dẫn tối ưu hóa và một số thư viện. Với OpenCL, bạn phải trải qua khá nhiều mã khởi tạo và viết các hạt nhân của bạn trong các chuỗi, vì vậy bạn chỉ tìm thấy các lỗi biên dịch trong khi thực thi khi cung cấp các nguồn cho trình biên dịch jit. Do đó, phải mất nhiều thời gian hơn để trải qua một chu kỳ mã / biên dịch / gỡ lỗi với OpenCL, do đó năng suất của bạn thường thấp hơn trong giai đoạn phát triển ban đầu này.
Các khía cạnh thư viện phần mềm. Mặc dù các mục trước đã ủng hộ CUDA, việc tích hợp vào các phần mềm khác là một điểm cộng lớn cho OpenCL. Bạn có thể sử dụng OpenCL bằng cách chỉ liên kết với thư viện OpenCL được chia sẻ và đó là nó, trong khi với CUDA, bạn bắt buộc phải có sẵn toàn bộ công cụ CUDA. Thậm chí tệ hơn, bạn cần sử dụng trình biên dịch máy chủ chính xác để nvcc hoạt động. Nếu bạn đã từng thử sử dụng CUDA 4.2 với GCC 4.6 hoặc mới hơn, bạn sẽ khó có thể làm việc được. Nói chung, nếu bạn có bất kỳ trình biên dịch nào được sử dụng mới hơn CUDA SDK, thì có thể xảy ra sự cố. Tích hợp vào các hệ thống xây dựng như CMake là một nguồn đau đầu khác (bạn cũng có thể tìm thấy nhiều bằng chứng về ví dụ như PETScdanh sách mail). Đây có thể không phải là vấn đề trên máy của bạn, nơi bạn có toàn quyền kiểm soát, nhưng ngay khi bạn phân phối mã của mình, bạn sẽ gặp phải tình huống người dùng bị hạn chế phần nào trong ngăn xếp phần mềm của họ. Nói cách khác, với CUDA, bạn không còn tự do chọn trình biên dịch máy chủ yêu thích của mình, nhưng NVIDIA chỉ ra trình biên dịch nào bạn được phép sử dụng.
Những khía cạnh khác. CUDA gần hơn một chút với phần cứng (ví dụ như warps), nhưng kinh nghiệm của tôi với đại số tuyến tính là bạn hiếm khi nhận được lợi ích đáng kể từ nó. Có một vài thư viện phần mềm ngoài kia cho CUDA, nhưng ngày càng có nhiều thư viện sử dụng nhiều phụ trợ tính toán. Trong khi đó, ViennaCL , VexCL hoặc Paralestion đều hỗ trợ các phụ trợ OpenCL và CUDA trong khi đó, một xu hướng tương tự có thể được nhìn thấy với các thư viện ở các khu vực khác.
GPGPU không phải là Viên đạn bạc. GPGPU đã được chứng minh là cung cấp hiệu suất tốt cho các hoạt động có cấu trúc và các nhiệm vụ giới hạn tính toán. Tuy nhiên, đối với các thuật toán có tỷ lệ xử lý tuần tự không đáng kể, GPGPU không thể vượt qua một cách kỳ diệu Định luật Amdahl . Trong những tình huống như vậy, tốt hơn hết bạn nên sử dụng một triển khai CPU tốt cho thuật toán tốt nhất hiện có thay vì cố gắng ném một thuật toán song song nhưng ít phù hợp hơn vào vấn đề của bạn. Ngoài ra, PCI-Express là một nút cổ chai nghiêm trọng, vì vậy bạn cần kiểm tra trước xem liệu các khoản tiết kiệm từ GPU có thể bù đắp chi phí cho việc di chuyển dữ liệu qua lại hay không.
Đề nghị của tôi. Vui lòng xem xét CUDA và OpenCL thay vì CUDA hoặcOpenCL. Không cần thiết phải hạn chế một cách không cần thiết vào một nền tảng, mà thay vào đó hãy tận dụng tốt nhất cả hai thế giới. Điều làm việc tốt với tôi là thiết lập một triển khai ban đầu trong CUDA, gỡ lỗi nó, cấu hình nó và sau đó chuyển nó sang OpenCL bằng cách thay thế chuỗi đơn giản. để điều chỉnh phần cứng đích.) Nỗ lực chuyển này thường sẽ tiêu tốn ít hơn 10 phần trăm thời gian của bạn, nhưng cũng cho bạn khả năng chạy trên phần cứng khác. Bạn có thể ngạc nhiên về việc phần cứng không phải của NVIDIA có thể hoạt động tốt như thế nào trong các tình huống nhất định. Trên hết, hãy xem xét việc sử dụng lại chức năng trong các thư viện ở mức độ lớn nhất có thể. Trong khi nhanh chóng & Việc thực hiện lại một số chức năng thường hoạt động có thể chấp nhận được khi thực hiện một luồng trên CPU, nó thường sẽ cung cấp cho bạn hiệu năng kém trên phần cứng song song. Lý tưởng nhất là bạn thậm chí có thể giảm tải mọi thứ cho các thư viện và không bao giờ phải quan tâm đến việc họ sử dụng CUDA, OpenCL hay cả nội bộ. Cá nhân tôi sẽ không bao giờ dám viết mã nhà cung cấp cho một cái gì đó mà tôi muốn dựa vào trong vài năm nữa, nhưng khía cạnh ý thức hệ này nên được đưa vào một cuộc thảo luận riêng.