Rumah >pembangunan bahagian belakang >C++ >Adakah Mentafsir Semula Hantaran Antara Penunjuk Vektor SIMD Perkakasan dan Jenis Sepadan Kelakuan Tidak Ditakrifkan dalam C ?

Adakah Mentafsir Semula Hantaran Antara Penunjuk Vektor SIMD Perkakasan dan Jenis Sepadan Kelakuan Tidak Ditakrifkan dalam C ?

DDD
DDDasal
2024-12-27 14:38:09243semak imbas

Is Reinterpreting Casts Between Hardware SIMD Vector Pointers and Corresponding Types Undefined Behavior in C  ?

Adakah Mentafsir Semula Pemutus Antara Penunjuk Vektor SIMD Perkakasan dan Jenis Sepadan Suatu Gelagat Yang Tidak Ditakrifkan?

Dalam C , adakah dibenarkan mentafsirkan semula apungan ke __m256 dan akses objek terapung melalui jenis penunjuk?

Contoh kod berikut menggambarkan ini:

#include <immintrin.h>

constexpr size_t _m256_float_step_sz = sizeof(__m256) / sizeof(float);
alignas(__m256) float stack_store[100 * _m256_float_step_sz ]{};
__m256& hwvec1 = *reinterpret_cast<__m256*&>(&stack_store[0 * _m256_float_step_sz]);

using arr_t = float[_m256_float_step_sz];
arr_t& arr1 = *reinterpret_cast<float(*)[_m256_float_step_sz]&>(&hwvec1);

Adakah hwvec1 dan arr1 mempunyai gelagat yang tidak ditentukan? Adakah peraturan aliasing yang ketat dilanggar ([basic.lval]/11)? Sebagai alternatif, adakah hanya satu cara intrinsik yang ditentukan:

__m256 hwvec2 = _mm256_load_ps(&stack_store[0 * _m256_float_step_sz]);
_mm256_store_ps(&stack_store[1 * _m256_float_step_sz], hwvec2);

Jawapan:

ISO C tidak mentakrifkan __m256, jadi kita perlu melihat apa yang mentakrifkan tingkah laku mereka pada pelaksanaan yang menyokong mereka. Intrinsik Intel mentakrifkan penunjuk vektor seperti __m256 sebagai dibenarkan untuk alias apa-apa lagi, dengan cara yang sama ISO C mentakrifkan char sebagai dibenarkan kepada alias. (Tetapi bukan sebaliknya: ia adalah UB dan pecah dalam amalan untuk menunjuk int* pada __m256i dan menafikannya.)

Jadi ya, adalah selamat untuk membatalkan rujukan __m256 dan bukannya menggunakan _mm256_load_ps( ) intrinsik beban sejajar. Tetapi terutamanya untuk float/double, selalunya lebih mudah untuk menggunakan intrinsik kerana ia juga menjaga tuangan dari float. Untuk integer, intrinsik muat/simpan AVX512 ditakrifkan sebagai mengambil batal tetapi AVX2 dan lebih awal memerlukan cast seperti (__m256i)&arr[i] yang merupakan reka bentuk API yang agak kikuk dan mengacaukan kod menggunakannya.

Beberapa intrinsik bukan AVX512 juga telah ditambah menggunakan void seperti movd/movq load/store alignment dan aliasing intrinsik selamat seperti _mm_loadu_si32(void). Sebelum ini saya fikir Intel menganggap anda akan menggunakan _mm_cvtsi32_si128 yang memerlukan int dimuatkan dengan selamat sendiri, yang bermaksud menggunakan memcpy untuk mengelakkan UB (sekurang-kurangnya pada penyusun selain ICC klasik dan MSVC, jika mereka membenarkan unaligned int* serta tidak menguatkuasakan ketat aliasing).

Ini mungkin berlaku sekitar masa Intel mula melihat untuk berhijrah ke LLVM untuk ICX/ICPX / OneAPI, dan menyedari betapa kucar-kacirnya untuk menangani beban sempit pada penyusun yang menguatkuasakan aliasing yang ketat.

Atas ialah kandungan terperinci Adakah Mentafsir Semula Hantaran Antara Penunjuk Vektor SIMD Perkakasan dan Jenis Sepadan Kelakuan Tidak Ditakrifkan dalam C ?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn