GPU Drano เป็นเครื่องมือวิเคราะห์แบบคงที่สำหรับโปรแกรม GPU หนึ่งในการวิเคราะห์ใน GPU Drano คือการค้นหาการเข้าถึงหน่วยความจำที่ไม่ได้รับการตรวจสอบในรหัส CUDA การวิเคราะห์อื่น ๆ ที่สนับสนุนโดย GPU Drano คือการวิเคราะห์เพื่อพิสูจน์ความเป็นอิสระของบล็อกขนาดของโปรแกรม GPU
มัด GPU ที่ทันสมัยเป็นด้ายเป็น Warps เธรดทั้งหมดในการดำเนินการวาร์ปดำเนินการใน Lockstep การเข้าถึงหน่วยความจำไปยังตำแหน่งหน่วยความจำที่แตกต่างกันสามารถรวมตัวกันเป็นโหลด/จัดเก็บเดียวหากหน่วยความจำอยู่ติดกันหรือ ใกล้พอ ในหน่วยความจำ เมื่อหน่วยความจำที่เข้าถึงได้โดย Warp อยู่ห่างกันจะต้องมีการโหลด/ร้านค้าหลายแห่งเพื่อทำธุรกรรมหน่วยความจำให้เสร็จสมบูรณ์และเราบอกว่าการเข้าถึงนั้น ไม่ได้รับการแก้ไข
เคอร์เนล GPU ถูกกล่าวว่าเป็น อิสระขนาดบล็อก หากการปรับเปลี่ยนขนาดบล็อกในขณะที่รักษาจำนวนเธรดทั้งหมดเดียวกันจะไม่ทำลายการทำงานของโปรแกรม นี่เป็นสิ่งจำเป็นสำหรับการปรับแต่งขนาดบล็อกที่ถูกต้องในโปรแกรม GPU ซึ่งมักใช้เพื่อปรับปรุงประสิทธิภาพของโปรแกรม
นอกจากนี้เรายังได้ดำเนินการวิเคราะห์แบบไดนามิกเพื่อระบุการเข้าถึงที่ไม่ได้รับการคัดเลือกซึ่งมีอยู่ในที่เก็บนี้
GPU DRANO ถูกนำมาใช้เป็นผ่านคอมไพเลอร์สำหรับ LLVM โดยใช้การใช้งาน CUDA โอเพ่นซอร์สของ Google: gpucc ดังนั้น Drano จึงถูกจับคู่กับ LLVM อย่างแน่นหนา
Drano ต้องการ LLVM เวอร์ชัน 6.0 หรือใหม่กว่า นอกจากนี้ยังต้องใช้ชุดเครื่องมือ CUDA (เวอร์ชัน 7.5 หรือใหม่กว่า) จาก Nvidia มันได้รับการทดสอบใน Ubuntu 16.04 LTS แต่ควรทำงานกับระบบ Linux ที่มีอยู่ส่วนใหญ่
การวิเคราะห์แบบคงที่นั้นไม่จำเป็นต้องใช้ GPU อย่างไรก็ตามในการดำเนินการโปรแกรมและเพื่อเรียกใช้ Dynamic Anlaysis จำเป็นต้องใช้ NVIDIA GPU และไดรเวอร์ที่เข้ากันได้ ตรวจสอบข้อกำหนดของระบบของ Nvidia สำหรับข้อมูลเพิ่มเติม
รายละเอียดของอัลกอริทึมและตัวเลือกการออกแบบสามารถพบได้ในเอกสารต่อไปนี้:
สคริปต์ installnrun.sh รวมถึงรายละเอียดโครงการขั้นตอนที่จำเป็นในการสร้างและดำเนินการ GPU Drano ในระบบ Ubuntu เพื่อเรียกใช้สคริปต์
ROOT_DIR ไปยังเส้นทางไปยังโฟลเดอร์ที่ดาวน์โหลดsh installnrun.shสิ่งนี้จะติดตั้ง GPU drano โดยอัตโนมัติบนระบบ Linux เราอธิบายขั้นตอนการติดตั้งเพิ่มเติมสำหรับการติดตั้งการวิเคราะห์การเข้าถึงที่ไม่ได้รับการคัดเลือกที่นี่ การติดตั้งสำหรับการวิเคราะห์ความเป็นอิสระขนาดบล็อก (หรือที่เรียกว่าการวิเคราะห์ค่าคงที่ขนาดบล็อก) สามารถทำได้ในทำนองเดียวกัน
รับ LLVM Source:
ตรวจสอบให้แน่ใจว่าติดตั้ง subversion ดาวน์โหลด LLVM เวอร์ชันใหม่ล่าสุด:
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
รับแหล่งที่มาดัง:
เปลี่ยนไดเรกทอรีการทำงานปัจจุบันของคุณเป็น llvm/tools/ และตรวจสอบ clang จากที่เก็บ SVN:
svn co http://llvm.org/svn/llvm-project/cfe/trunk clang
เพิ่ม GPU drano ไปยัง LLVM:
คัดลอก src/ โฟลเดอร์ของ GPU Drano ลงในไดเรกทอรี llvm/lib/Transforms/UncoalescedAnalysis ในซอร์สโค้ดของคุณ:
cp -r src/abstract-execution/* llvm/lib/Transforms/UncoalescedAnalysis
cp -r src/uncoalesced-analysis/* llvm/lib/Transforms/UncoalescedAnalysis
สิ่งนี้จะสร้างโฟลเดอร์ที่เรียกว่า llvm/lib/Transforms/UncoalescedAnalysis/ เราต้องลงทะเบียนบัตรผ่านของเราด้วยระบบสร้าง LLVM, cmake ดังนั้นผนวก add_subdirectory(UncoalescedAnalysis) ไปยัง llvm/lib/Transforms/CMakeLists.txt
ตัวอย่างไฟล์ cmakelists.txt:
$> more CMakeLists.txt
add_subdirectory(Utils)
add_subdirectory(Instrumentation)
add_subdirectory(InstCombine)
add_subdirectory(Scalar)
add_subdirectory(IPO)
add_subdirectory(Vectorize)
add_subdirectory(Hello)
add_subdirectory(ObjCARC)
add_subdirectory(Coroutines)
add_subdirectory(UncoalescedAnalysis)
สร้าง LLVM และ GPU DRANO:
จากไดเรกทอรีรากของ Drano สร้าง build/ Directory จากนั้นเปลี่ยนไดเรกทอรีเป็น build/ Directory ตรวจสอบให้แน่ใจว่ามีการติดตั้ง CMake ในระบบ ดำเนินการคำสั่งต่อไปนี้ที่นี่:
cmake ../llvm
make
นั่นคือ cmake กับเส้นทางไปยังไดเรกทอรี LLVM ( ../llvm ) CMAKE กำหนดค่า LLVM สำหรับระบบของคุณ ควรสร้างไฟล์หลายไฟล์ในไดเรกทอรีการทำงานปัจจุบันของคุณ ( build/ ) คำสั่ง make Builds LLVM และ DRANO
เป็นการดีที่ใช้ make -j N โดยที่ n คือจำนวนแกนของคุณที่จะสร้างด้วยขนานกันเนื่องจาก LLVM ใช้เวลานานในการสร้าง
ข้อสังเกต : LLVM Build ใช้หน่วยความจำจำนวนมากในการรวบรวมโดยเฉพาะที่ขั้นตอนการเชื่อมโยง หากคุณมี <8 กิกะไบต์ของ RAM, LLVM อาจไม่สามารถสร้างได้ ถ้าเป็นเช่นนั้นคุณสามารถรัน make ได้โดยไม่ต้องตัวเลือก -j สิ่งนี้จะคอมไพล์ส่วนที่ล้มเหลวของบิลด์อีกครั้งและยังคงประหยัดเวลามากกว่าที่จะไม่ใช้ -j ตั้งแต่เริ่มต้น
ติดตั้ง LLVM และ GPU Drano ดำเนินการ sudo make install สิ่งนี้ควรติดตั้งไลบรารีและไบนารีในตำแหน่งเริ่มต้น (หรือตำแหน่งที่ระบุ) หากติดตั้งในเครื่องคู่มือนี้จะถือว่า Bash สามารถค้นหาคำสั่งในเส้นทางของมัน
ข้างต้นเป็นคู่มือเริ่มต้นอย่างรวดเร็ว หากคุณไม่คุ้นเคยกับ LLVM คุณอาจพบรายละเอียดทั้งหมดสำหรับการติดตั้งที่: http://llvm.org/docs/gettingstarted.html
สคริปต์ installnrun.sh อธิบายกระบวนการสั้น ๆ เพื่อสร้างไดรเวอร์ Nvidia, Toolkit และ SDK สคริปต์ได้รับการแสดงความคิดเห็นเพื่อหลีกเลี่ยงความเสี่ยงของการเอาชนะไดรเวอร์ Nvidia ที่มีอยู่ โปรดทราบว่าเราต้องการชุดเครื่องมือและ SDK เพื่อเรียกใช้การวิเคราะห์แบบคงที่ นอกจากนี้เรายังต้องการไดรเวอร์และ GPU ที่ใช้งานได้เพื่อดำเนินการวิเคราะห์แบบไดนามิกและโปรแกรม CUDA ด้วยตนเอง
ติดตั้งไดรเวอร์ NVIDIA, CUDA Toolkit และ SDK: โปรดดูคู่มือการติดตั้ง NVIDIA สำหรับคำแนะนำ
โดยสรุปหากคุณใช้ Linux Distro ล่าสุดและเป็นที่นิยมคุณควรใช้เครื่องมือดาวน์โหลดอัตโนมัติเพื่อติดตั้งไดรเวอร์และ SDK ที่จำเป็น
หากคุณมีไดรเวอร์ที่จำเป็นและ SDK ที่ติดตั้งอยู่แล้วคุณสามารถข้ามขั้นตอนนี้ได้ อาจไม่ใช่ความคิดที่ดีที่จะแทนที่ไดรเวอร์ที่มีอยู่ของคุณเนื่องจากอาจทำให้ระบบของคุณใช้ไม่ได้
คุณอาจต้องการ G ++-Multilib เพื่อติดตั้งไลบรารีที่จำเป็นโดย clang
ขั้นตอนนี้เป็น ทางเลือก โปรแกรม CUDA ง่าย ๆ เช่น "Hello World" ควรรวบรวมโดยใช้ clang หรือ clang++ :
clang -x cuda helloWorld.cu
ตัวเลือก -x cuda ระบุภาษาอย่างชัดเจน คุณอาจละเว้นได้เช่นกันและเสียงดังจะอนุมานว่านี่เป็นโปรแกรม CUDA
ข้อสังเกต: การติดตั้งระบบของคุณอาจไม่สามารถหาฟังก์ชั่น LLVM ภายในได้หลายอย่างถ้าเป็นเช่นนั้นคุณอาจต้องรวม -lcudart คุณอาจต้องชี้ไปที่ที่ตั้งของ cudart.so
ตัวอย่าง:
clang -x cuda -L /usr/local/cuda/targets/x86_64-linux/lib/ -lcudart helloWorld.cu
เส้นทางไปยัง cudart.so ของคุณ อาจแตกต่างกันไปขึ้นอยู่กับระบบของคุณ
LLVM ควรสร้างไฟล์ที่ใช้ร่วมกันไฟล์ .so ที่เรียกว่า LLVMUncoalescedAnalysis.so ภายใต้ build/lib/ ไดเรกทอรี
clang ผู้ร้องเรียน LLVM สร้างอุปกรณ์แยกต่างหาก (รหัสเคอร์เนล GPU) และโฮสต์ (รหัสเรียกใช้บน CPU) ไฟล์ IR เมื่อรวบรวมโปรแกรม CUDA GPU Drano วิเคราะห์ไฟล์ LLVM IR สำหรับรหัสอุปกรณ์
ตัวอย่างเช่นลองวิเคราะห์รหัสเคอร์เนล Rodinia สำหรับเกณฑ์มาตรฐาน gaussian เราเปลี่ยนไดเรกทอรีเป็น rodinia_3.1/cuda/gaussian/
ก่อนอื่นเราให้ clang สร้างไฟล์ LLVM IR สำหรับรหัสที่เราสนใจ:
clang++ -S -g -emit-llvm gaussian.cu
ขอให้สังเกตว่าเรารวบรวมด้วยสัญลักษณ์การดีบัก -g เพื่อเก็บข้อมูลการดีบักเกี่ยวกับตำแหน่งซอร์สโค้ดใน IR ที่สร้างขึ้น สิ่งนี้ใช้ในการชี้ตำแหน่งซอร์สโค้ดที่มีการเข้าถึงที่ไม่ได้รับการตรวจสอบจาก LLVM IR
การรวบรวมสร้างสองไฟล์:
gaussian-cuda-nvptx64-nvidia-cuda-sm_20.ll
gaussian.ll
จากนั้นเราสามารถเรียกใช้การวิเคราะห์แบบคงที่ผ่าน opt ของ LLVM โดยการระบุเส้นทางไปยัง GPU Drano Binary และระบุ Pass -interproc-uncoalesced-analysis ที่จะเรียกใช้ บัตรผ่านนี้เป็นการวิเคราะห์ระหว่างกระบวนการเพื่อตรวจจับการเข้าถึงที่ไม่ได้รับการคัดเลือก มันเริ่มต้นด้วยการวิเคราะห์ฟังก์ชั่นสูงสุดในกราฟโทรจากนั้นดำเนินการกับการวิเคราะห์ callees ตามลำดับโทโพโลยี ในขณะที่วิเคราะห์ Callee ที่เฉพาะเจาะจงจะพิจารณาการเข้าร่วมของบริบทการโทรของผู้โทรทั้งหมด ในการเรียกใช้การวิเคราะห์ intraprocedural (ซึ่งถือว่าอาร์กิวเมนต์ฟังก์ชั่นเริ่มต้นทั้งหมดนั้นเป็นอิสระจาก ID ของเธรด) ระบุ -uncoalesced-analysis ที่จะเรียกใช้แทน -interproc-uncoalesced-analysis
opt -load ../../../build/lib/LLVMUncoalescedAnalysis.so -instnamer -interproc-uncoalesced-analysis < gaussian-cuda-nvptx64-nvidia-cuda-sm_20.ll > /dev/null 2> gpuDranoResults.txt
ประกาศ opt อ่านไฟล์ IR จากอินพุตมาตรฐาน opt Writes เป็นเอาท์พุทที่ไม่น่าสนใจของตัวเองเพื่อออกไปมาตรฐานดังนั้นเราจึงเปลี่ยนเส้นทางไปยัง /dev/null GPU Drano เอาต์พุตของ DRANO ถูกเขียนไปยังข้อผิดพลาดมาตรฐานซึ่งอาจถูกเปลี่ยนเส้นทางไปยังไฟล์
ในการสร้างผลการวิเคราะห์ verbose (LLVM IR บันทึกคำอธิบายประกอบด้วยข้อมูลการวิเคราะห์) ให้เรียก opt ด้วย -debug-only=uncoalesced-analysis เพิ่มเติม
คำสั่งต่อไปนี้สามารถใช้เพื่อเรียกใช้การวิเคราะห์ความเป็นอิสระของบล็อกในโปรแกรม
opt -load ../../../build/lib/LLVMBlockSizeInvarianceAnalysis.so - -instnamer -always-inline -interproc-bsize-invariance-analysis < gaussian-cuda-nvptx64-nvidia-cuda-sm_20.ll > /dev/null 2> gpuDranoResults.txt
ผลลัพธ์ที่สร้างขึ้นสำหรับการวิเคราะห์การเข้าถึงที่ไม่ได้รับการตรวจสอบการเข้าถึงทั้งหมดที่อาจเกิดขึ้นในแต่ละเมล็ด GPU ตัวอย่างเช่นนี่คือผลลัพธ์สำหรับการวิเคราะห์ gaussian.cu
Analysis Results:
Function: _Z4Fan1PfS_ii
Uncoalesced accesses: #2
-- gaussian.cu:295:59
-- gaussian.cu:295:61
Analysis Results:
Function: _Z4Fan2PfS_S_iii
Uncoalesced accesses: #4
-- gaussian.cu:312:38
-- gaussian.cu:312:35
-- gaussian.cu:312:35
-- gaussian.cu:317:23
รายการผลลัพธ์แต่ละรายการชี้ไปที่การเข้าถึงที่ไม่ได้รับการตรวจสอบในซอร์สโค้ด ตัวอย่างเช่นการเข้าถึง m_cuda ที่บรรทัดที่ 295, คอลัมน์ 59 ใน gaussian.cu ที่วิธีการ Fan1() ถูก uncoalesced
ในทำนองเดียวกันผลลัพธ์ที่สร้างขึ้นสำหรับการวิเคราะห์ความเป็นอิสระขนาดบล็อกระบุเมล็ดทั้งหมดที่เป็นอิสระขนาดบล็อก!
Rodinia เป็นชุดเกณฑ์มาตรฐานยอดนิยมของโปรแกรม GPU ประกอบด้วย 22 โปรแกรมจากโดเมนที่แตกต่างกัน เราวิเคราะห์ห้องสวีทและพบการเข้าถึงที่ไม่ได้รับการคัดเลือกจริง 111 ครั้งโดยใช้การวิเคราะห์แบบคงที่ ในการทำซ้ำผลลัพธ์นี่คือขั้นตอนที่เกี่ยวข้อง:
อัปเดตการกำหนดค่า CUDA และ DRANO ใน rodinia_3.1/common/make.config ตั้งค่า CUDA_DIR และ SDK_DIR ด้วยเส้นทางเครื่องมือ NVIDIA และเส้นทาง SDK อัปเดตนามแฝง opt พร้อมเส้นทางไปยัง GPU DRANO Binary LLVMUncoalescedAnalysis.so
ไปที่ Directory Directory rodinia_3.1/cuda
คอมไพล์เกณฑ์มาตรฐาน:
sh compile.sh
sh run-analysis.sh
การวิเคราะห์ของแต่ละเกณฑ์มาตรฐานสร้างผลลัพธ์ในโฟลเดอร์ที่เกี่ยวข้องในไฟล์บันทึกชื่อ log_<filename>
./summarize-results.sh
Nvidia จัดเตรียมชุดตัวอย่าง CUDA ซึ่งสามารถใช้สำหรับแอปพลิเคชันต่างๆ เราวิเคราะห์ชุดเพื่อระบุเมล็ดอิสระขนาดบล็อกในตัวอย่าง ในการทำซ้ำผลลัพธ์ขั้นตอนคือ:
อัปเดตตัวแปร HOME ใน NVIDIA_CUDA-8.0_Samples/common/drano.mk ไปยังไดเรกทอรี Root GPU Drano
ติดตั้ง OpenGL (จำเป็นสำหรับการรวบรวมเกณฑ์มาตรฐานสองสามครั้ง) บน Ubuntu สามารถใช้คำสั่งต่อไปนี้:
sudo apt-get install freeglut3-dev
ไปที่ไดเรกทอรี NVIDIA_CUDA-8.0_Samples
คอมไพล์เกณฑ์มาตรฐาน:
sh compile.sh
sh run-analysis.sh
การวิเคราะห์ของแต่ละเกณฑ์มาตรฐานสร้างผลลัพธ์ในโฟลเดอร์ที่เกี่ยวข้องในไฟล์บันทึกชื่อ log_<filename>
./summarize-bsize-independence.sh