“ vectorization” คืออะไร


190

หลายครั้งในขณะนี้ฉันได้พบคำศัพท์นี้ใน matlab, fortran ... บางคน ... แต่ฉันไม่เคยพบคำอธิบายความหมายและสิ่งที่มันทำ? ผมเลยถามตรงนี้, เวกเตอร์คืออะไร, และมันมีความหมายว่าอะไร, ตัวอย่างเช่น "a loop is vectorized"?


1
@geoffspear ดูเหมือนว่าลิงค์จะถูกย้ายไปที่en.wikipedia.org/wiki/Array_programming
ฉันชอบ Code

คำตอบ:


225

ซีพียูจำนวนมากมีชุดคำสั่ง "vector" หรือ "SIMD" ซึ่งใช้การดำเนินการเดียวกันพร้อมกันกับข้อมูลสอง, สี่หรือมากกว่า ชิพ x86 รุ่นใหม่มีคำสั่ง SSE ชิป PPC จำนวนมากมีคำสั่ง "Altivec" และแม้แต่ชิป ARM บางอันก็มีชุดคำสั่งเวกเตอร์เรียกว่า NEON

"Vectorization" (ลดความซับซ้อน) เป็นกระบวนการของการเขียนลูปใหม่ดังนั้นแทนที่จะประมวลผลองค์ประกอบเดียวของอาเรย์ N ครั้งมันประมวลผล (พูด) องค์ประกอบ 4 ของอาเรย์พร้อมกัน N / 4 ครั้ง

(ฉันเลือก 4 เพราะเป็นฮาร์ดแวร์ที่ทันสมัยที่สุดที่สนับสนุนโดยตรงมากที่สุดคำว่า "vectorization" ยังใช้เพื่ออธิบายการแปลงซอฟต์แวร์ระดับสูงขึ้นซึ่งคุณอาจแยกวงออกไปโดยสิ้นเชิงและอธิบายการทำงานบนอาร์เรย์แทนองค์ประกอบ ที่ประกอบด้วยพวกเขา)


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

for (int i=0; i<16; ++i)
    C[i] = A[i] + B[i];

การยกเลิกการวนซ้ำนี้จะเปลี่ยนเป็นอะไรแบบนี้:

for (int i=0; i<16; i+=4) {
    C[i]   = A[i]   + B[i];
    C[i+1] = A[i+1] + B[i+1];
    C[i+2] = A[i+2] + B[i+2];
    C[i+3] = A[i+3] + B[i+3];
}

ในทางกลับกันการทำให้ Vectorizing เป็นเช่นนี้:

for (int i=0; i<16; i+=4)
    addFourThingsAtOnceAndStoreResult(&C[i], &A[i], &B[i]);

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


11
อะไรคือความแตกต่างระหว่างสิ่งนี้กับการคลี่คลาย / วนซ้ำ?
Jeremy Powell

1
ไม่เป็นความจริงหรือว่าคอมไพเลอร์จะมีงานที่ง่ายขึ้นอัตโนมัติ-vectorizing วนซ้ำที่ไม่ได้ควบคุม?
Nikos Athanasiou

@ NikosAthanasiou: มันเป็นไปได้ แต่โดยทั่วไปแล้วการพูดภาษาคอมไพเลอร์น่าจะสามารถทำการตรวจสอบทั้งสองวงได้โดยอัตโนมัติเนื่องจากมันเรียบง่ายมาก
Stephen Canon

1
@StephenCanon จะตรวจสอบได้อย่างไรว่ามีบางบรรทัดถูกทำให้เป็นเวกเตอร์หรือไม่? ถ้าใครจะใช้ objdump เราจะมองหาอะไรในผลลัพธ์ของ objdump?
user1823664

3
@Shuklaswag: vectorization เป็นสิ่งที่คอมไพเลอร์สามารถทำเพื่อคุณได้ แต่มันก็เป็นสิ่งที่โปรแกรมเมอร์ทำเองอย่างชัดเจน ระบบปฏิบัติการไม่เกี่ยวข้อง
Stephen Canon

32

Vectorization เป็นคำสำหรับการแปลงโปรแกรมสเกลาร์ไปเป็นโปรแกรมเวกเตอร์ โปรแกรม Vectorized สามารถเรียกใช้การดำเนินการหลายอย่างจากคำสั่งเดียวในขณะที่สเกลาร์สามารถทำงานกับคู่ของตัวถูกดำเนินการในครั้งเดียวเท่านั้น

จากวิกิพีเดีย :

วิธีเกลา:

for (i = 0; i < 1024; i++)
{
   C[i] = A[i]*B[i];
}

วิธีการ Vectorized:

for (i = 0; i < 1024; i+=4)
{
   C[i:i+3] = A[i:i+3]*B[i:i+3];
}

นั่นไม่ใช่สาระสำคัญเหมือนกับแนวทางสเกลาร์หรือ ไวยากรณ์และการวนลูปของคุณแตกต่างกัน แต่ภายใต้คุณยังคงคูณมัน 4 ครั้ง แต่อย่างใดมันอาจจะเร็วกว่าซีพียูอาจมีคำสั่งที่ใช้เคล็ดลับบางอย่างที่เรียกว่า Vectorization
mskw

ดูเหมือนว่าฉันจะตอบคำถามของฉันเองที่นี่ ไวยากรณ์ในวิธีการ vectorization เมื่อ complier เห็นว่ามันจะแปลมันเป็นคำสั่ง CPU ที่เพิ่มประสิทธิภาพที่คูณเวกเตอร์ ชอบ SIMD
mskw

10

มันหมายถึงความสามารถในการดำเนินการทางคณิตศาสตร์เดียวในรายการ - หรือ "เวกเตอร์" - ของตัวเลขในขั้นตอนเดียว คุณเห็นบ่อยครั้งกับ Fortran เพราะมันเกี่ยวข้องกับการคำนวณทางวิทยาศาสตร์ซึ่งเกี่ยวข้องกับการคำนวณแบบซูเปอร์ซึ่งการคำนวณทางคณิตศาสตร์แบบเวกเตอร์ปรากฏขึ้นครั้งแรก ทุกวันนี้ซีพียูเดสก์ท็อปเกือบทุกตัวเสนอการคำนวณแบบเวกเตอร์บางส่วนผ่านเทคโนโลยีเช่น SSE ของ Intel GPUs ยังเสนอรูปแบบของเวกเตอร์คณิตศาสตร์


7

Vectorizationถูกนำมาใช้อย่างมากในการคำนวณทางวิทยาศาสตร์ที่จำเป็นต้องประมวลผลข้อมูลจำนวนมากอย่างมีประสิทธิภาพ

ในแอปพลิเคชันการเขียนโปรแกรมจริงฉันรู้ว่ามันใช้ใน NUMPY (ไม่แน่ใจในสิ่งอื่น)

Numpy (แพ็คเกจสำหรับการคำนวณทางวิทยาศาสตร์ในไพ ธ อน) ใช้vectorizationสำหรับการจัดการอาเรย์ n-มิติอย่างรวดเร็วซึ่งโดยทั่วไปจะช้ากว่าหากทำด้วยตัวเลือกของไพ ธ อนในการสร้างอาเรย์

แม้ว่าตันของคำอธิบายออกมีนี่คือสิ่งที่vectorizationถูกกำหนดให้เป็นในNumPy เอกสารหน้า

Vectorization จะอธิบายถึงการขาดการวนซ้ำอย่างชัดเจนการจัดทำดัชนี ฯลฯ ในโค้ด - สิ่งเหล่านี้กำลังเกิดขึ้นแน่นอนว่า“ เบื้องหลัง” ในโค้ด C ที่ปรับแต่งล่วงหน้า รหัส Vectorized มีข้อดีหลายประการซึ่ง ได้แก่ :

  1. รหัส vectorized กระชับและอ่านง่ายขึ้น

  2. โดยทั่วไปบรรทัดที่น้อยลงหมายถึงข้อบกพร่องที่น้อยลง

  3. รหัสใกล้เคียงกับสัญกรณ์คณิตศาสตร์มาตรฐานมากขึ้น (ทำให้ง่ายขึ้นโดยทั่วไปเพื่อสร้างรหัสทางคณิตศาสตร์ที่ถูกต้อง)

  4. ผล vectorization ในรหัส“ Pythonic” เพิ่มเติม โค้ดของเราจะเกลื่อนไปด้วยลูปที่ไม่มีประสิทธิภาพและอ่านยากสำหรับลูป


4

Vectorization กล่าวง่ายๆว่าหมายถึงการปรับอัลกอริธึมให้เหมาะสมเพื่อให้สามารถใช้คำสั่ง SIMD ในโปรเซสเซอร์ได้

AVX, AVX2 และ AVX512 เป็นชุดคำสั่ง (intel) ที่ทำงานเหมือนกันกับข้อมูลจำนวนมากในหนึ่งคำสั่ง สำหรับเช่น AVX512 หมายถึงคุณสามารถดำเนินการกับค่าจำนวนเต็ม 16 ค่า (4 ไบต์) ในแต่ละครั้ง นั่นหมายความว่าถ้าคุณมีเวกเตอร์จำนวนเต็ม 16 ตัวและคุณต้องการเพิ่มค่านั้นเป็นสองเท่าในแต่ละจำนวนเต็มจากนั้นบวก 10 ลงไป คุณสามารถโหลดค่าลงในการลงทะเบียนทั่วไป [a, b, c] 16 ครั้งและทำการดำเนินการเดียวกันหรือคุณสามารถดำเนินการเดียวกันโดยโหลด 16 ค่าทั้งหมดลงในการลงทะเบียน SIMD [xmm, ymm] และดำเนินการหนึ่งครั้ง สิ่งนี้จะช่วยเพิ่มความเร็วในการคำนวณข้อมูลเวกเตอร์

ในการทำให้เป็น vectorization เราใช้สิ่งนี้เพื่อประโยชน์ของเราโดยการปรับปรุงข้อมูลของเราเพื่อให้เราสามารถดำเนินการกับ SIMD และเพิ่มความเร็วของโปรแกรม

ปัญหาเกี่ยวกับ vectorization เท่านั้นคือเงื่อนไขการจัดการ เนื่องจากเงื่อนไขแยกการไหลของการดำเนินการ สิ่งนี้สามารถจัดการได้โดยการปิดบัง โดยการสร้างแบบจำลองเงื่อนไขลงในการดำเนินการทางคณิตศาสตร์ เช่น. ถ้าเราต้องการเพิ่ม 10 ให้เป็นค่าถ้ามันมากกว่า 100 เราก็ทำได้

if(x[i] > 100) x[i] += 10; // this will branch execution flow.

หรือเราสามารถสร้างโมเดลเงื่อนไขลงในการดำเนินการทางคณิตศาสตร์เพื่อสร้างเงื่อนไขเวกเตอร์ c

c[i] = x[i] > 100; // storing the condition on masking vector
x[i] = x[i] + (c[i] & 10) // using mask

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

Vectorization มีความสำคัญพอ ๆ กัน ดังนั้นเราควรใช้ให้มากที่สุด โปรเซสเซอร์ยุคใหม่ทั้งหมดมีคำแนะนำ SIMD สำหรับการคำนวณภาระงานหนัก เราสามารถเพิ่มประสิทธิภาพโค้ดของเราเพื่อใช้คำแนะนำ SIMD เหล่านี้โดยใช้ vectorization ซึ่งคล้ายกับการทำให้โค้ดของเราทำงานแบบขนานเพื่อให้ทำงานบนหลายคอร์ที่มีอยู่ในโปรเซสเซอร์ที่ทันสมัย

ฉันอยากจะออกไปพร้อมกับกล่าวถึง OpenMP ซึ่งจะช่วยให้คุณปรับเวกเตอร์โค้ดด้วย pragmas ได้ ฉันคิดว่ามันเป็นจุดเริ่มต้นที่ดี เดียวกันสามารถพูดได้สำหรับ OpenACC


0

โดยคน Intel ฉันคิดว่าเข้าใจง่าย

Vectorization เป็นกระบวนการของการแปลงอัลกอริทึมจากการดำเนินการกับค่าเดียวในแต่ละครั้งเพื่อดำเนินการกับชุดของค่าในครั้งเดียว CPU สมัยใหม่ให้การสนับสนุนโดยตรงสำหรับการทำงานของเวกเตอร์ที่มีการใช้คำสั่งเดียวกับหลายข้อมูล (SIMD)

ตัวอย่างเช่น CPU ที่มีการลงทะเบียน 512 บิตสามารถถือ 16 32- บิตความแม่นยำเดี่ยวคู่และทำการคำนวณเดียว

เร็วกว่าการรันคำสั่งครั้งละ 16 เท่า รวมสิ่งนี้เข้ากับเธรดและซีพียูแบบมัลติคอร์นำไปสู่คำสั่งของประสิทธิภาพที่เพิ่มขึ้น

ลิงก์https://software.intel.com/en-us/articles/vectorization-a-key-tool-to-improve-performance-on-modern-cpus

ใน Java มีตัวเลือกสำหรับสิ่งนี้รวมอยู่ใน Jdk 15 ปี 2020 หรือล่าช้าที่ JDK 16 ที่ 2021

https://bugs.openjdk.java.net/browse/JDK-8201271


-4

ดูคำตอบสองข้อด้านบน ฉันแค่อยากจะเพิ่มว่าเหตุผลที่ต้องการทำ vectorization คือการดำเนินการเหล่านี้สามารถทำได้อย่างง่ายดายในพาราเซลโดยซุปเปอร์คอมพิวเตอร์และโปรเซสเซอร์หลายตัวทำให้ได้รับประสิทธิภาพที่ยิ่งใหญ่ ในคอมพิวเตอร์ตัวประมวลผลเดียวจะไม่มีประสิทธิภาพเพิ่มขึ้น


12
"ในคอมพิวเตอร์ตัวประมวลผลเดียวจะไม่มีประสิทธิภาพเพิ่มขึ้น": ไม่จริง ตัวประมวลผลที่ทันสมัยส่วนใหญ่มีการสนับสนุนฮาร์ดแวร์ (จำกัด ) สำหรับ vectorization (SSE, Altivec. ฯลฯ ตามชื่อโดย stephentyrone) ซึ่งสามารถเพิ่มความเร็วได้อย่างมากเมื่อใช้
sleske

ขอบคุณฉันลืมการขนานที่สามารถทำได้ในระดับนั้นเช่นกัน
Larry Watanabe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.