CUDA คืออะไร? การเขียนโปรแกรมแบบขนานสำหรับ GPU

CUDA เป็นแพลตฟอร์มการประมวลผลแบบขนานและรูปแบบการเขียนโปรแกรมที่พัฒนาโดย Nvidia สำหรับการประมวลผลทั่วไปบน GPU ของตัวเอง (หน่วยประมวลผลกราฟิก) CUDA ช่วยให้นักพัฒนาสามารถเร่งความเร็วแอปพลิเคชันที่ต้องใช้การประมวลผลมากขึ้นโดยใช้ประโยชน์จากพลังของ GPU สำหรับส่วนที่ขนานกันได้ของการคำนวณ

ในขณะที่มีการเสนอ API อื่น ๆ สำหรับ GPU เช่น OpenCL และมี GPU ที่แข่งขันได้จาก บริษัท อื่น ๆ เช่น AMD การรวมกันของ CUDA และ Nvidia GPUs เข้าครอบงำพื้นที่แอปพลิเคชันต่างๆรวมถึงการเรียนรู้เชิงลึกและเป็นรากฐานสำหรับบางส่วนของ คอมพิวเตอร์ที่เร็วที่สุดในโลก

กราฟิกการ์ดนั้นมีเนื้อหาที่เก่าพอ ๆ กับพีซีนั่นคือถ้าคุณถือว่า IBM Monochrome Display Adapter ปี 1981 เป็นกราฟิกการ์ด ภายในปี 1988 คุณจะได้รับการ์ด VGA Wonder 16 บิตแบบ 16 บิตจาก ATI (บริษัท ได้เข้าซื้อกิจการโดย AMD ในที่สุด) ภายในปีพ. ศ. 2539 คุณสามารถซื้อตัวเร่งกราฟิก 3D จาก 3dfx Interactive เพื่อให้คุณสามารถเรียกใช้ Quake ของนักกีฬาคนแรกได้ด้วยความเร็วเต็มที่

นอกจากนี้ในปี 2539 Nvidia เริ่มพยายามแข่งขันในตลาดเครื่องเร่ง 3D ด้วยผลิตภัณฑ์ที่อ่อนแอ แต่ก็เรียนรู้ไปเรื่อย ๆ และในปี 2542 ได้เปิดตัว GeForce 256 ซึ่งเป็นกราฟิกการ์ดตัวแรกที่เรียกว่า GPU ในเวลานั้นเหตุผลหลักของการมี GPU คือเพื่อการเล่นเกม จนกระทั่งในเวลาต่อมาผู้คนใช้ GPU สำหรับคณิตศาสตร์วิทยาศาสตร์และวิศวกรรม

ที่มาของ CUDA

ในปี 2546 ทีมนักวิจัยที่นำโดย Ian Buck ได้เปิดตัว Brook ซึ่งเป็นรูปแบบการเขียนโปรแกรมที่ได้รับการยอมรับอย่างกว้างขวางเป็นครั้งแรกเพื่อขยาย C ด้วยโครงสร้างแบบขนานข้อมูล หลังจากนั้น Buck ได้เข้าร่วมกับ Nvidia และเป็นผู้นำในการเปิดตัว CUDA ในปี 2549 ซึ่งเป็นโซลูชันเชิงพาณิชย์ตัวแรกสำหรับการประมวลผลทั่วไปบน GPU

OpenCL เทียบกับ CUDA

CUDA คู่แข่งของ OpenCL เปิดตัวโดย Apple และ Khronos Group ในปี 2552 เพื่อพยายามสร้างมาตรฐานสำหรับการประมวลผลที่แตกต่างกันซึ่งไม่ จำกัด เฉพาะซีพียู Intel / AMD ที่มี Nvidia GPU แม้ว่า OpenCL จะฟังดูน่าสนใจเนื่องจากลักษณะทั่วไป แต่ก็ยังทำงานได้ไม่ดีเท่ากับ CUDA บน Nvidia GPUs และเฟรมเวิร์กการเรียนรู้เชิงลึกจำนวนมากไม่รองรับหรือสนับสนุนในภายหลังเมื่อการสนับสนุน CUDA ของพวกเขาได้รับการเผยแพร่แล้ว

เพิ่มประสิทธิภาพ CUDA

CUDA ได้ปรับปรุงและขยายขอบเขตในช่วงหลายปีที่ผ่านมาไม่มากก็น้อยในขั้นตอนการปิดกั้นด้วย Nvidia GPU ที่ได้รับการปรับปรุง ตั้งแต่ CUDA เวอร์ชัน 9.2 โดยใช้ GPU เซิร์ฟเวอร์ P100 หลายตัวคุณจะได้รับการปรับปรุงประสิทธิภาพมากกว่าซีพียูถึง 50 เท่า V100 (ไม่แสดงในรูปนี้) เร็วขึ้นอีก 3 เท่าสำหรับบางโหลด เซิร์ฟเวอร์ GPU รุ่นก่อนหน้าคือ K80 นำเสนอการปรับปรุงประสิทธิภาพ 5x ถึง 12x เมื่อเทียบกับ CPU

Nvidia

การเร่งความเร็วจาก GPU เป็นช่วงเวลาสั้น ๆ สำหรับการประมวลผลประสิทธิภาพสูง การเพิ่มประสิทธิภาพของซีพียูแบบเธรดเดียวเมื่อเวลาผ่านไปซึ่งกฎของมัวร์แนะนำว่าจะเพิ่มขึ้นเป็นสองเท่าทุก ๆ 18 เดือนได้ชะลอตัวลงถึง 10 เปอร์เซ็นต์ต่อปีเนื่องจากผู้ผลิตชิปพบข้อ จำกัด ทางกายภาพรวมถึงขีด จำกัด ขนาดความละเอียดของชิปมาสก์และผลผลิตของชิปในระหว่างกระบวนการผลิต และขีดจำกัดความร้อนของความถี่สัญญาณนาฬิกาที่รันไทม์

Nvidia

โดเมนแอปพลิเคชัน CUDA

Nvidia

CUDA และ Nvidia GPUs ถูกนำมาใช้ในหลายพื้นที่ที่ต้องการประสิทธิภาพการประมวลผลแบบทศนิยมสูงดังที่สรุปเป็นภาพในภาพด้านบน รายการที่ครอบคลุมมากขึ้น ได้แก่ :

  1. การเงินเชิงคำนวณ
  2. การสร้างแบบจำลองสภาพภูมิอากาศสภาพอากาศและมหาสมุทร
  3. วิทยาศาสตร์ข้อมูลและการวิเคราะห์
  4. การเรียนรู้เชิงลึกและการเรียนรู้ของเครื่อง
  5. การป้องกันและข่าวกรอง
  6. การผลิต / AEC (สถาปัตยกรรมวิศวกรรมและการก่อสร้าง): CAD และ CAE (รวมถึงพลศาสตร์ของไหลเชิงคำนวณกลศาสตร์โครงสร้างเชิงคำนวณการออกแบบและการแสดงภาพและการออกแบบอัตโนมัติทางอิเล็กทรอนิกส์)
  7. สื่อและความบันเทิง (รวมถึงแอนิเมชั่นการสร้างแบบจำลองและการแสดงผลการแก้ไขสีและการจัดการเกรนการจัดองค์ประกอบการตกแต่งและเอฟเฟกต์การแก้ไขการเข้ารหัสและการกระจายแบบดิจิทัลกราฟิกออนแอร์ออนเซ็ตตรวจสอบและเครื่องมือสเตอริโอและกราฟิกสภาพอากาศ)
  8. ถ่ายภาพทางการแพทย์
  9. น้ำมันและก๊าซ
  10. การวิจัย: การศึกษาระดับสูงและซูเปอร์คอมพิวเตอร์ (รวมถึงเคมีเชิงคำนวณและชีววิทยาการวิเคราะห์เชิงตัวเลขฟิสิกส์และการสร้างภาพทางวิทยาศาสตร์)
  11. ความปลอดภัยและความปลอดภัย
  12. เครื่องมือและการจัดการ

CUDA ในการเรียนรู้เชิงลึก

การเรียนรู้เชิงลึกมีความต้องการความเร็วในการประมวลผลสูง ตัวอย่างเช่นในการฝึกโมเดลสำหรับ Google Translate ในปี 2016 ทีม Google Brain และ Google Translate ได้ดำเนินการ TensorFlow หนึ่งสัปดาห์หลายร้อยครั้งโดยใช้ GPU พวกเขาซื้อ GPU ระดับเซิร์ฟเวอร์ 2,000 ตัวจาก Nvidia เพื่อจุดประสงค์ หากไม่มี GPU การฝึกอบรมเหล่านี้จะต้องใช้เวลาหลายเดือนมากกว่าหนึ่งสัปดาห์ในการรวม สำหรับการใช้งานจริงของโมเดลการแปล TensorFlow เหล่านั้น Google ได้ใช้ชิปประมวลผลแบบกำหนดเองใหม่คือ TPU (หน่วยประมวลผลเทนเซอร์)

นอกเหนือจาก TensorFlow แล้วเฟรมเวิร์ก DL อื่น ๆ อีกมากมายยังใช้ CUDA สำหรับการรองรับ GPU ของพวกเขาเช่น Caffe2, CNTK, Databricks, H2O.ai, Keras, MXNet, PyTorch, Theano และ Torch ในกรณีส่วนใหญ่พวกเขาใช้ไลบรารี cuDNN สำหรับการคำนวณเครือข่ายประสาทเทียมระดับลึก ไลบรารีนั้นมีความสำคัญอย่างยิ่งต่อการฝึกอบรมของกรอบการเรียนรู้เชิงลึกซึ่งกรอบงานทั้งหมดที่ใช้ cuDNN เวอร์ชันที่กำหนดจะมีตัวเลขประสิทธิภาพเดียวกันสำหรับกรณีการใช้งานที่เทียบเท่ากัน เมื่อ CUDA และ cuDNN ปรับปรุงจากเวอร์ชันหนึ่งเป็นเวอร์ชันหนึ่งเฟรมเวิร์กการเรียนรู้เชิงลึกทั้งหมดที่อัปเดตเป็นเวอร์ชันใหม่จะเห็นประสิทธิภาพที่เพิ่มขึ้น ในกรณีที่ประสิทธิภาพมีแนวโน้มที่จะแตกต่างกันไปในแต่ละเฟรมเวิร์กคือการปรับขนาดให้เป็น GPU หลายตัวและหลายโหนด

การเขียนโปรแกรม CUDA

Nvidia

CUDA Toolkit

CUDA Toolkit ประกอบด้วยไลบรารีเครื่องมือดีบักและการปรับให้เหมาะสมคอมไพเลอร์เอกสารประกอบและไลบรารีรันไทม์เพื่อปรับใช้แอปพลิเคชันของคุณ มีส่วนประกอบที่สนับสนุนการเรียนรู้เชิงลึกพีชคณิตเชิงเส้นการประมวลผลสัญญาณและอัลกอริทึมแบบขนาน โดยทั่วไปแล้วไลบรารี CUDA รองรับ Nvidia GPU ทุกตระกูล แต่ทำงานได้ดีที่สุดในรุ่นล่าสุดเช่น V100 ซึ่งเร็วกว่า P100 ถึง 3 เท่าสำหรับภาระงานการฝึกอบรมการเรียนรู้เชิงลึก การใช้ไลบรารีอย่างน้อยหนึ่งไลบรารีเป็นวิธีที่ง่ายที่สุดในการใช้ประโยชน์จาก GPU ตราบเท่าที่มีการใช้อัลกอริทึมที่คุณต้องการในไลบรารีที่เหมาะสม

Nvidia

ห้องสมุดการเรียนรู้เชิงลึกของ CUDA

ในขอบเขตการเรียนรู้เชิงลึกมีไลบรารีที่เร่งด้วย GPU หลักสามไลบรารี: cuDNN ซึ่งฉันได้กล่าวไว้ก่อนหน้านี้ว่าเป็นส่วนประกอบของ GPU สำหรับเฟรมเวิร์กการเรียนรู้เชิงลึกแบบโอเพนซอร์สส่วนใหญ่ TensorRT ซึ่งเป็นเครื่องมือเพิ่มประสิทธิภาพการอนุมานและรันไทม์การเรียนรู้เชิงลึกประสิทธิภาพสูงของ Nvidia และ DeepStream ซึ่งเป็นไลบรารีการอนุมานวิดีโอ TensorRT ช่วยให้คุณปรับโมเดลเครือข่ายประสาทเทียมให้เหมาะสมปรับเทียบเพื่อความแม่นยำที่ต่ำกว่าด้วยความแม่นยำสูงและปรับใช้โมเดลที่ผ่านการฝึกอบรมกับคลาวด์ศูนย์ข้อมูลระบบฝังตัวหรือแพลตฟอร์มผลิตภัณฑ์ยานยนต์

Nvidia

พีชคณิตเชิงเส้น CUDA และไลบรารีคณิตศาสตร์

พีชคณิตเชิงเส้นรองรับการคำนวณเทนเซอร์ดังนั้นการเรียนรู้เชิงลึก BLAS (โปรแกรมย่อยพีชคณิตเชิงเส้นพื้นฐาน) ซึ่งเป็นชุดของอัลกอริทึมเมทริกซ์ที่นำมาใช้ใน Fortran ในปี 1989 ถูกนำมาใช้โดยนักวิทยาศาสตร์และวิศวกร cuBLAS เป็น BLAS เวอร์ชันเร่ง GPU และเป็นวิธีที่มีประสิทธิภาพสูงสุดในการคำนวณเมทริกซ์ด้วย GPU cuBLAS ถือว่าเมทริกซ์มีความหนาแน่น cuSPARSE จัดการเมทริกซ์แบบเบาบาง

Nvidia

ไลบรารีประมวลผลสัญญาณ CUDA

การแปลงฟูเรียร์อย่างรวดเร็ว (FFT) เป็นหนึ่งในอัลกอริทึมพื้นฐานที่ใช้สำหรับการประมวลผลสัญญาณ มันเปลี่ยนสัญญาณ (เช่นรูปคลื่นเสียง) เป็นสเปกตรัมของความถี่ cuFFT คือ FFT ที่เร่งด้วย GPU

ตัวแปลงสัญญาณโดยใช้มาตรฐานเช่น H.264 เข้ารหัส / บีบอัดและถอดรหัส / คลายการบีบอัดวิดีโอสำหรับการส่งและการแสดงผล Nvidia Video Codec SDK ทำให้กระบวนการนี้เร็วขึ้นด้วย GPU

Nvidia

ไลบรารีอัลกอริทึมแบบขนานของ CUDA

ไลบรารีทั้งสามสำหรับอัลกอริทึมแบบขนานล้วนมีวัตถุประสงค์ที่แตกต่างกัน NCCL (Nvidia Collective Communications Library) มีไว้สำหรับการปรับขนาดแอปใน GPU และโหนดต่างๆ nvGRAPH ใช้สำหรับการวิเคราะห์กราฟคู่ขนาน และ Thrust คือไลบรารีเทมเพลต C ++ สำหรับ CUDA ตามไลบรารีเทมเพลตมาตรฐาน C ++ Thrust ให้คอลเลกชันแบบขนานของข้อมูลที่หลากหลายเช่นการสแกนจัดเรียงและลด

Nvidia

CUDA เทียบกับประสิทธิภาพของ CPU

ในบางกรณีคุณสามารถใช้ฟังก์ชัน CUDA แบบดรอปอินแทนฟังก์ชัน CPU ที่เทียบเท่าได้ ตัวอย่างเช่นรูทีนการคูณเมทริกซ์ GEMM จาก BLAS สามารถแทนที่ด้วยเวอร์ชัน GPU ได้ง่ายๆเพียงแค่ลิงก์ไปยังไลบรารี NVBLAS:

Nvidia

พื้นฐานการเขียนโปรแกรม CUDA

หากคุณไม่พบรูทีนไลบรารี CUDA เพื่อเร่งโปรแกรมของคุณคุณจะต้องลองใช้โปรแกรม CUDA ระดับต่ำ ตอนนี้ง่ายกว่าตอนที่ฉันลองครั้งแรกในช่วงปลายยุค 2000 ด้วยเหตุผลอื่น ๆ คือมีไวยากรณ์ที่ง่ายกว่าและมีเครื่องมือในการพัฒนาที่ดีกว่า การเล่นลิ้นเพียงอย่างเดียวของฉันคือใน MacOS คอมไพเลอร์ CUDA ล่าสุดและคอมไพเลอร์ C ++ ล่าสุด (จาก Xcode) ไม่ค่อยซิงค์กัน ต้องดาวน์โหลดเครื่องมือบรรทัดคำสั่งรุ่นเก่าจาก Apple และเปลี่ยนไปใช้xcode-selectเพื่อรับรหัส CUDA เพื่อรวบรวมและเชื่อมโยง

ตัวอย่างเช่นพิจารณารูทีน C / C ++ ง่ายๆนี้เพื่อเพิ่มอาร์เรย์สองอาร์เรย์:

โมฆะเพิ่ม (int n, float * x, float * y)

{  

       สำหรับ (int i = 0; i <n; i ++)      

             y [i] = x [i] + y [i];

}

คุณสามารถเปลี่ยนเป็นเคอร์เนลที่จะทำงานบน GPU ได้โดยเพิ่ม__global__คีย์เวิร์ดในการประกาศและเรียกเคอร์เนลโดยใช้ไวยากรณ์วงเล็บสามอัน:

เพิ่ม << >> (N, x, y);

นอกจากนี้คุณยังมีการเปลี่ยนแปลงของคุณmalloc/ newและfree/ deleteโทรไปcudaMallocManagedและcudaFreeเพื่อให้คุณได้รับการจัดสรรพื้นที่บนของ GPU สุดท้ายคุณก็ต้องรอการคำนวณ GPU ให้สมบูรณ์ก่อนที่จะใช้ผลการค้นหาบน CPU cudaDeviceSynchronizeซึ่งคุณสามารถประสบความสำเร็จกับ

ตัวยึดสามตัวด้านบนใช้หนึ่งบล็อกเธรดและเธรด Nvidia GPU ปัจจุบันสามารถรองรับบล็อกและเธรดจำนวนมากได้ ตัวอย่างเช่น Tesla P100 GPU ที่ใช้สถาปัตยกรรม Pascal GPU มีตัวประมวลผลแบบ Streaming Multiprocessors (SM) 56 ตัวซึ่งแต่ละตัวสามารถรองรับเธรดที่ใช้งานได้ถึง 2048 เธรด

รหัสเคอร์เนลจะต้องทราบดัชนีบล็อกและเธรดเพื่อหาค่าชดเชยในอาร์เรย์ที่ส่งผ่าน เคอร์เนลแบบขนานมักใช้การวนซ้ำแบบกริดดังต่อไปนี้:

__global__

โมฆะเพิ่ม (int n, float * x, float * y)

{

   ดัชนี int = blockIdx.x * blockDim.x + threadIdx.x;

   int stride = blockDim.x * gridDim.x;

   สำหรับ (int i = index; i <n; i + = stride)

     y [i] = x [i] + y [i];

}

หากคุณดูตัวอย่างใน CUDA Toolkit คุณจะเห็นว่ามีอะไรให้พิจารณามากกว่าพื้นฐานที่ฉันกล่าวไว้ข้างต้น ตัวอย่างเช่นการเรียกใช้ฟังก์ชัน CUDA บางอย่างจำเป็นต้องรวมอยู่ในการcheckCudaErrors()โทร นอกจากนี้ในหลาย ๆ กรณีโค้ดที่เร็วที่สุดจะใช้ไลบรารีเช่นการcuBLASจัดสรรโฮสต์และหน่วยความจำอุปกรณ์และการคัดลอกเมทริกซ์ไปมา

โดยสรุปคุณสามารถเร่งความเร็วแอปของคุณด้วย GPU ได้หลายระดับ คุณสามารถเขียนโค้ด CUDA คุณสามารถเรียกไลบรารี CUDA และคุณสามารถใช้แอพพลิเคชั่นที่รองรับ CUDA อยู่แล้ว