คำถามต่อไปนี้เป็นเรื่องที่เกี่ยวข้อง แต่คำตอบที่มีความเก่าแก่และความคิดเห็นจากผู้ใช้มาร์ค Glisseแสดงให้เห็นมีวิธีการใหม่ตั้งแต่ C ++ 17 เพื่อแก้ไขปัญหานี้ที่อาจจะไม่ได้รับการกล่าวถึงอย่างเพียงพอ
ฉันกำลังพยายามให้หน่วยความจำที่ทำงานสอดคล้องกันอย่างถูกต้องสำหรับ SIMD ในขณะที่ยังคงสามารถเข้าถึงข้อมูลทั้งหมดได้
ใน Intel ถ้าฉันสร้างเวกเตอร์ลอยชนิด__m256
และลดขนาดลง 8 เท่ามันจะทำให้ฉันมีหน่วยความจำที่สอดคล้องกัน
เช่น std::vector<__m256> mvec_a((N*M)/8);
ในทางที่แฮ็กเล็กน้อยฉันสามารถชี้พอยน์เตอร์ไปยังองค์ประกอบเวกเตอร์เพื่อลอยตัวซึ่งทำให้ฉันสามารถเข้าถึงค่าลอยตัวส่วนบุคคล
แต่ฉันต้องการให้มีการstd::vector<float>
จัดตำแหน่งที่ถูกต้องและสามารถโหลดลงใน__m256
และ SIMD ประเภทอื่น ๆ ได้โดยไม่ต้องแบ่งไฟล์
ฉันได้รับการมองเข้าไปในaligned_alloc
นี่สามารถให้อาเรย์แบบ C ที่จัดเรียงอย่างถูกต้อง:
auto align_sz = static_cast<std::size_t> (32);
float* marr_a = (float*)aligned_alloc(align_sz, N*M*sizeof(float));
อย่างไรก็ตามฉันไม่แน่ใจว่าจะทำเช่นนี้std::vector<float>
ได้อย่างไร ให้std::vector<float>
เป็นเจ้าของไม่ได้ดูเหมือนจะเป็นไปได้marr_a
ฉันเคยเห็นคำแนะนำบางอย่างที่ฉันควรเขียนตัวจัดสรรแบบกำหนดเองแต่ดูเหมือนว่าจะทำงานได้มากและบางทีด้วย C ++ ที่ทันสมัยมีวิธีที่ดีกว่า
_mm256_loadu_ps(&vec[i])
หรือไม่มีการชะลอตัวที่อาจเกิดขึ้นจากการแยกแคชเส้นเมื่อคุณใช้ (ถึงแม้จะทราบว่ามีตัวเลือกการปรับแต่งค่าเริ่มต้น GCC แยกไม่รับประกัน-ชิดโหลด 256-bit / ร้านค้าเข้า vmovups XMM / vinsertf128. จึงมีเป็นข้อได้เปรียบในการใช้_mm256_load
มากกว่าloadu
ถ้าคุณดูแลเกี่ยวกับวิธีการคอมไพล์รหัสของคุณใน GCC ถ้าลืมใครสักคน ใช้-mtune=...
หรือ-march=
ตัวเลือก)