ฉันจะพยายามสรุปประสบการณ์ของฉันที่ได้รับในระหว่างการพัฒนา ViennaCL ที่ซึ่งเรามีแบ็กเอนด์ CUDA และ OpenCL ที่มีการแปล 1: 1 ของเมล็ดคำนวณจำนวนมาก จากคำถามของคุณฉันจะสมมติว่าเราใช้ GPU เป็นส่วนใหญ่ที่นี่
ประสิทธิภาพการพกพาก่อนอื่นไม่มีสิ่งเช่นเมล็ดแบบพกพาประสิทธิภาพในแง่ที่ว่าคุณเขียนเคอร์เนลเพียงครั้งเดียวและมันจะทำงานได้อย่างมีประสิทธิภาพบนฮาร์ดแวร์ทุกตัว ไม่ใช่ใน OpenCL ซึ่งมีความชัดเจนมากขึ้นเนื่องจากรองรับฮาร์ดแวร์ในวงกว้างกว่า แต่ยังไม่ได้อยู่ใน CUDA ใน CUDA นั้นมีความชัดเจนน้อยกว่าเนื่องจากรองรับฮาร์ดแวร์ที่มีขนาดเล็กกว่า แต่ที่นี่เราต้องแยกความแตกต่างอย่างน้อยสามสถาปัตยกรรมฮาร์ดแวร์ (pre-Fermi, Fermi, Kepler) แล้ว ความผันผวนของประสิทธิภาพการทำงานเหล่านี้อาจส่งผลให้เกิดความแปรปรวนของประสิทธิภาพได้ร้อยละ 20 ขึ้นอยู่กับวิธีที่คุณจัดการกับเธรดและขนาดของกลุ่มงานที่คุณเลือกแม้ว่าเคอร์เนลจะง่ายเหมือนกับการคัดลอกบัฟเฟอร์ อาจเป็นเรื่องที่ควรค่าแก่การกล่าวถึงใน Pre-Fermi และ Fermi GPU มันเป็นไปได้ที่จะเขียนเคอร์เนลการคูณเมทริกซ์เมทริกซ์ที่รวดเร็วโดยตรงใน CUDA ในขณะที่สำหรับ Kepler GPU ล่าสุดดูเหมือนว่าจะต้องใช้ภาษา PTX หลอกประกอบเพื่อให้ได้ใกล้เคียงกับประสิทธิภาพของ CUBLAS ดังนั้นแม้แต่ภาษาที่ควบคุมโดยผู้จำหน่ายเช่น CUDA ก็ยังมีปัญหาในการพัฒนาฮาร์ดแวร์ ยิ่งไปกว่านั้นรหัส CUDA ทั้งหมดได้รับการรวบรวมแบบสแตติกเมื่อคุณเรียกใช้ nvcc ซึ่งต้องการการปรับสมดุลผ่านทางแฟล็ก -arch ในขณะที่เมล็ด OpenCL ได้รับการคอมไพล์ในเวลาทำงานจากคอมไพเลอร์ทันเวลาเพื่อให้คุณสามารถ ลงไปที่เฉพาะเจาะจงมากของอุปกรณ์คำนวณ อย่างไรก็ตามส่วนหลังนั้นเกี่ยวข้องกันมากและมักจะกลายเป็นตัวเลือกที่น่าสนใจมากเมื่อโค้ดของคุณเติบโตขึ้นและเมื่อประสบการณ์ของคุณสะสม ราคาที่ต้องชำระคือเวลา O (1) ที่จำเป็นสำหรับการรวบรวมแบบทันเวลาซึ่งอาจเป็นปัญหาในบางสถานการณ์ OpenCL 2
การดีบักและการทำโปรไฟล์ เครื่องมือการดีบักและสร้างโปรไฟล์ CUDA นั้นดีที่สุดสำหรับ GPGPU เครื่องมือของเอเอ็มดีก็ไม่ได้เลวร้ายเช่นกัน แต่ไม่รวมอัญมณีเช่น cuda-gdb หรือ cuda-memcheck นอกจากนี้ในวันนี้ NVIDIA ยังมอบไดร์เวอร์และ SDK ที่แข็งแกร่งที่สุดสำหรับ GPGPU ซึ่งระบบหยุดทำงานเนื่องจากเคอร์เนล buggy นั้นเป็นข้อยกเว้นจริงๆไม่ใช่กฎรวมทั้ง OpenCL และ CUDA ด้วยเหตุผลที่ฉันอาจไม่จำเป็นต้องอธิบายที่นี่ NVIDIA ไม่ให้การดีบักและการทำโปรไฟล์สำหรับ OpenCL กับ CUDA 5.0 ขึ้นไปอีกต่อไป
การเข้าถึงและความสะดวกสบาย เป็นการง่ายกว่ามากที่จะได้รับรหัส CUDA ครั้งแรกและทำงานโดยเฉพาะอย่างยิ่งเนื่องจากรหัส CUDA รวมค่อนข้างดีกับรหัสโฮสต์ (ฉันจะพูดถึงราคาที่จะจ่ายในภายหลัง) มีบทแนะนำมากมายบนเว็บรวมถึงคู่มือการเพิ่มประสิทธิภาพและห้องสมุดบางแห่ง ด้วย OpenCL คุณต้องผ่านโค้ดเริ่มต้นเล็กน้อยและเขียนเมล็ดของคุณเป็นสตริงดังนั้นคุณจะพบข้อผิดพลาดในการคอมไพล์ระหว่างการดำเนินการเมื่อป้อนแหล่งข้อมูลไปยัง jit-compiler ดังนั้นจึงใช้เวลานานกว่าในการผ่านหนึ่งรหัส / คอมไพล์ / ดีบั๊กรอบกับ OpenCL ดังนั้นผลผลิตของคุณมักจะต่ำกว่าในช่วงการพัฒนาเริ่มต้นนี้
ด้านห้องสมุดซอฟต์แวร์ ในขณะที่รายการก่อนหน้านี้เป็นที่นิยมของ CUDA การรวมเข้ากับซอฟต์แวร์อื่นเป็นข้อดีอย่างยิ่งสำหรับ OpenCL คุณสามารถใช้ OpenCL เพียงแค่เชื่อมโยงกับไลบรารี OpenCL ที่ใช้ร่วมกันและใช้งานได้ในขณะที่คุณต้องใช้ CUDA toolchain ทั้งหมดพร้อม CUDA คุณต้องใช้คอมไพเลอร์โฮสต์ที่ถูกต้องเพื่อให้ nvcc ทำงานได้ หากคุณเคยลองใช้เช่น CUDA 4.2 กับ GCC 4.6 หรือใหม่กว่าคุณจะมีเวลาในการทำงานหลายอย่าง โดยทั่วไปหากคุณมีคอมไพเลอร์ที่ใช้งานซึ่งใหม่กว่า CUDA SDK อาจมีปัญหาเกิดขึ้น การรวมเข้ากับระบบการสร้างเช่น CMake เป็นแหล่งที่ทำให้ปวดหัวอีกแหล่งหนึ่ง (คุณสามารถพบหลักฐานมากมายเช่นPETScเมล) นี่อาจไม่ใช่ปัญหาในเครื่องของคุณที่คุณสามารถควบคุมได้อย่างสมบูรณ์ แต่ทันทีที่คุณแจกจ่ายรหัสของคุณคุณจะพบกับสถานการณ์ที่ผู้ใช้ถูก จำกัด ในสแต็กซอฟต์แวร์ของพวกเขา กล่าวอีกนัยหนึ่งด้วย CUDA คุณไม่ต้องเสียเวลาเลือกโฮสต์คอมไพเลอร์ที่คุณชื่นชอบอีกต่อไป แต่ NVIDIA สั่งให้คอมไพเลอร์ตัวใดที่คุณได้รับอนุญาตให้ใช้
ด้านอื่น ๆ CUDA นั้นใกล้กับฮาร์ดแวร์เล็กน้อย (เช่น warps) แต่ประสบการณ์ของฉันกับพีชคณิตเชิงเส้นคือคุณไม่ค่อยได้รับประโยชน์อย่างมากจากมัน มีห้องสมุดซอฟต์แวร์อยู่สองสามแห่งสำหรับ CUDA แต่มีห้องสมุดจำนวนมากที่ใช้แบ็กเอนด์การคำนวณหลาย ๆ ViennaCL , VexCLหรือParalutionทั้งหมดสนับสนุน OpenCL และ CUDA แบ็กเอนด์ในขณะเดียวกันแนวโน้มที่คล้ายกันสามารถมองเห็นได้ด้วยห้องสมุดในพื้นที่อื่น ๆ
GPGPU ไม่ใช่ Bullet เงิน GPGPU ได้รับการแสดงเพื่อให้มีประสิทธิภาพที่ดีสำหรับการดำเนินงานที่มีโครงสร้างและงานคำนวณที่ จำกัด อย่างไรก็ตามสำหรับขั้นตอนวิธีการที่มีส่วนแบ่งไม่น้อยของการประมวลผลตามลำดับ GPGPU ไม่สามารถเอาชนะได้อย่างน่าอัศจรรย์กฎหมายของดาห์ล ในสถานการณ์เช่นนี้คุณจะดีกว่าด้วยการใช้ซีพียูที่ดีของอัลกอริธึมที่ดีที่สุดที่มีอยู่แทนที่จะพยายามโยนขนาน แต่อัลกอริทึมที่เหมาะสมน้อยกว่าที่ปัญหาของคุณ นอกจากนี้ PCI-Express เป็นคอขวดที่ร้ายแรงดังนั้นคุณต้องตรวจสอบล่วงหน้าว่าการประหยัดจาก GPU สามารถชดเชยค่าใช้จ่ายในการเคลื่อนย้ายข้อมูลไปมาได้หรือไม่
คำแนะนำของฉัน โปรดพิจารณา CUDA และ OpenCL มากกว่า CUDA หรือOpenCL ไม่จำเป็นต้อง จำกัด ตัวเองโดยไม่จำเป็นกับแพลตฟอร์มเดียว แต่ให้ใช้ประโยชน์จากทั้งสองโลกให้ดีที่สุด สิ่งที่ดีสำหรับฉันคือการตั้งค่าการใช้งานเริ่มต้นใน CUDA ตรวจแก้จุดบกพร่องโปรไฟล์แล้วพอร์ตไปยัง OpenCL โดยการแทนที่สตริงแบบง่าย ๆ (คุณอาจทำให้ parametrize รูทีนการสร้างสตริงของ OpenCL ของคุณเช่นว่าคุณมีความยืดหยุ่นบ้าง ในการปรับให้เข้ากับฮาร์ดแวร์เป้าหมาย) ความพยายามในการย้ายพอร์ตนี้โดยปกติจะใช้เวลาน้อยกว่า 10 เปอร์เซ็นต์ของเวลาของคุณ แต่ให้ความสามารถในการทำงานกับฮาร์ดแวร์อื่น ๆ ได้เช่นกัน คุณอาจแปลกใจว่าฮาร์ดแวร์ที่ไม่ใช่ของ NVIDIA สามารถทำงานได้ดีในบางสถานการณ์ ส่วนใหญ่พิจารณาการนำฟังก์ชั่นการใช้งานกลับมาใช้ใหม่ในไลบรารีให้มากที่สุดเท่าที่จะเป็นไปได้ ในขณะที่ & การปรับใช้สกปรกของฟังก์ชั่นบางอย่างมักจะทำงานได้ดีสำหรับการประมวลผลแบบเธรดเดียวบน CPU มันมักจะให้ประสิทธิภาพที่ไม่ดีกับฮาร์ดแวร์แบบขนานขนาดใหญ่ เป็นการดีที่คุณสามารถถ่ายทุกอย่างลงในห้องสมุดและไม่ต้องสนใจว่าจะใช้ CUDA, OpenCL หรือทั้งสองอย่างภายใน โดยส่วนตัวฉันจะไม่กล้าเขียนรหัสล็อคผู้ขายสำหรับสิ่งที่ฉันต้องการพึ่งพาในหลายปีต่อจากนี้ แต่ด้านอุดมการณ์นี้ควรจะไปอภิปรายแยก