Flamboyan


Menuju SIMD kenal takut

Aku akan menggunakannya sangat luas di synthesizer saya, dan juga itu semakin digunakan dalam xi-editor untuk perbandingan string mengoptimalkan dan primitif yang sama. SIMD adalah teknik kinerja yang kuat, dan sangat berharga dalam sinyal dan pengolahan gambar applications.Rust memiliki potensi untuk menjadi salah satu bahasa terkemuka untuk SIMD, tapi kondisi saat ini cukup kasar. Dalam posting ini, saya akan berangkat tantangan, hasil dari beberapa eksplorasi saya, dan saran untuk hal-hal untuk meningkatkan. Sampai saat ini, pendekatan yang paling praktis menulis kode perakitan, yang sangat arcane.In visi ini, programmer menulis perhitungan menggunakan tingkat tinggi, aman, primitif composable, yang kemudian kompilasi ke kode hampir sempurna untuk setiap tingkat kemampuan SIMD dari arsitektur target, dengan seleksi runtime otomatis. operasi SIMD lebih eksotis terkena, portable jika memungkinkan, tetapi juga dengan pintu keluar darurat menggunakan intrinsik prosesor khusus ketika mereka benar-benar diperlukan. Saya sebut visi saya untuk apa saya akan seperti Rust untuk mencapai "tak kenal takut SIMD," dalam analogi dengan "tak kenal takut concurrency" .Saya sangat senang dengan fakta bahwa SIMD sekarang merupakan bagian dari stabil Rust, tapi kondisi saat ini sangat jauh dari "tak kenal takut". Saya sudah menerbitkan peti disebut fearless_simd, tapi nama itu lebih merupakan aspirasi dari janji terpenuhi.Masalah lebih mudah adalah kompilasi kode untuk dijalankan pada sebuah chip target tunggal, memilih pada waktu kompilasi yang terbaik dari beberapa alternatif berdasarkan capaibilities SIMD. Menulis kode SIMD untuk chip tertentu jauh, jauh lebih mudah daripada menulis kode yang akan berjalan dengan baik di beragam chip. Tantangan-tingkat berikutnya adalah menyusun beberapa alternatif ke dalam biner yang sama, dan memilih yang terbaik di runtime.Code dilindungi oleh penjaga tersebut kemudian dapat menggunakan SIMD intrinsik untuk tingkat itu, tetapi ini semua ditandai sebagai tidak aman karena compiler tidak statis memeriksa bahwa kemampuan sebenarnya hadir. Kemudian, sebagai bagian dari dukungan SIMD di stabil, ada mekanisme # yang kondisional mengkompilasi kode didasarkan pada fitur yang tersedia untuk CPU target yang dipilih. The Rust compiler memberikan solusi untuk tingkat pertama tantangan, setidaknya untuk programmer berani. Ini memiliki bendera target cpu, yang mengarahkan ke kode produk untuk tertentu chip.For seleksi runtime, compiler Rust menyediakan beberapa alat mentah, tapi itu sepenuhnya terserah programmer untuk menempatkan mereka bersama-sama dengan benar. Ada penjelasan untuk selektif "turn on" kemampuan SIMD untuk fungsi tunggal, dan is_x86_feature_detected! makro untuk mendeteksi pada saat runtime.Lebih mendalam, yang # atribut yang bekerja dengan baik untuk deteksi kompilasi tidak lagi bekerja untuk deteksi runtime, karena itu diselesaikan terlalu dini, dan tidak bisa memberikan jawaban untuk pertanyaan, "apa kemampuan telah menegaskan dalam fungsi yang sebaris saya" ? Ada beberapa diskusi dengan pointer ke jawaban yang potensial, tapi take pribadi saya adalah bahwa ini adalah masalah mendasar yang pada akhirnya akan membutuhkan perubahan bahasa yang mendalam ke alamat. Ini bekerja cukup baik ketika, seperti tradisional, logika SIMD-spesifik ditulis sebagai sebuah blok di dalam berfungsi.Tindakan peti tunggal dirancang untuk memudahkan deteksi runtime, dan menulis logika yang sebenarnya tanpa duplikasi, tapi daun penulisan sebenarnya dari arsitektur tertentu shims kepada pengguna, dan masih membutuhkan trivial tidak aman code.It juga layak mengambil melihat lebih dalam pada apa yang dilakukan dunia C / C ++, seperti yang saat ini yang paling matang ekosistem untuk pembangunan SIMD. Saya pikir salah satu diskusi yang lebih besar ke depan adalah sejauh mana beradaptasi bahasa ini dan fitur tingkat runtime ke dalam bahasa Rust. Meskipun SIMD bukan bagian dari bahasa standar, baik GCC dan dentang memiliki ekstensi vektor. Ada juga dukungan untuk Fungsi multi Versi, yang sangat baik didukung pada Linux .Intel ini ISPC mengambil ide ekstensi bahasa untuk SIMD lebih jauh, dan pada dasarnya merupakan perluasan dari C dirancang khusus sekitar kompilasi kode portabel untuk kinerja tinggi SIMD. Ada dukungan bahkan untuk ARM Neon, tapi tentu saja fokus utama adalah chip Intel.
Terakhir, bahasa Halide dirancang terutama untuk pengolahan gambar, dan target tidak hanya SIMD tetapi juga GPU komputasi. Dalam bermain dengan itu, saya tidak yakin itu cocok untuk beban kerja audio, tapi worth itu mencari at.While saya pikir itu mungkin bahwa Rust harus berevolusi untuk dukungan yang lebih baik SIMD, saya ingin menjelajahi seberapa jauh hal itu mungkin untuk pergi menggunakan Rust karena ada saat ini. Ini tentu bukan solusi tujuan umum untuk masalah ini, tapi berdasarkan percobaan saya sejauh ini, saya pikir itu mungkin dapat digunakan untuk beberapa ciri things.These sebagian besar metode yang aman, membungkus unsafety yang mendasari, meskipun metode tentu saja tidak aman juga disediakan jika diperlukan sebagai pintu keluar darurat. Secara khusus, menciptakan nilai implementasi SIMD tertentu adalah operasi yang tidak aman, karena tergantung pada deteksi runtime dari SIMD capability.Also, monomorphization Rust ini mengurus secara otomatis menghasilkan beberapa versi dari kode untuk tingkat SIMD beberapa, termasuk fallback skalar yang bekerja pada arsitektur apapun. Kemudian, pelari arsitektur tertentu mendeteksi tingkat SIMD saat runtime, dan panggilan ke dalam sifat dengan implementasi konkret yang sesuai. Semakin tinggi tingkat sifat mewakili beberapa yang ditentukan pengguna komputasi, generik atas semua implementasi konkret dari sifat SIMD. pelari aman, menggunakan deteksi runtime untuk menjaga panggilan yang tidak aman secara internal untuk versi SIMD yang khusus.Satu mewakili transformasi skalar sederhana dari f32 ke f32, dan yang lainnya adalah thunk yang dapat cukup banyak perhitungan apapun, yakni tidak terbatas pada iterator, dan dapat melakukan akses acak menjadi irisan, dll saya bisa membayangkan lebih, seperti -> fungsi f32, tapi aku akan menerapkan ini karena saya membutuhkan mereka.itu mengatakan, GeneratorF32 sifat dirancang sehingga penciptaan iterator terjadi di dalam pembungkus target_feature, yang harus baik mengurangi kemungkinan memicu bug itu, dan meningkatkan kualitas kode. Menggunakan peti ini sangat sensitif terhadap inlining, sebuah mendapatkan salah kehendak memicu karat-lang / karat # 50154.For contoh, fitur deteksi runtime mungkin menunjukkan bahwa AVX-512 tersedia, namun pengguna dapat memilih untuk menggunakan hanya AVX2 untuk alasan kinerja .suatu batas sifat yang relevan melakukan pekerjaan jika ditambahkan ke sifat SimdF32, tapi itu akan memaksa banyak boilerplate dalam implementasi klien, karena karat-lang / karat # 23.856. Jika x memiliki nilai SimdF32, adalah mungkin untuk menulis, misalnya, x + 1.0, tapi saat ini 1,0 + x tidak work.I'm benar-benar menggali ke dalam dan berusaha untuk memperbaikinya, dan itu masalah mengejutkan dalam di dan dari dirinya sendiri, mungkin subyek masa depan blog posting. Juga saat mengevaluasi kinerja melalui benchmark, saya menemukan bahwa operasi putaran di Rust sangat slow.On sisi lain, saya berencana untuk menggunakannya sebanyak mungkin untuk mengembangkan pemrosesan sinyal dan visualisasi algoritma di synthesizer saya, menambahkan kemampuan untuk Perpustakaan. Saya pasti akan menerima permintaan tarik untuk kasus penggunaan secara luas selaras dengan arah arus peti.Apa ciri-ciri terbaik untuk mewakili perhitungan generik yang dapat diimplementasikan secara efisien dalam SIMD? Seberapa jauh kita bisa pergi menggunakan saat ini stabil Rust, dan sejauh mana ekstensi untuk bahasa akan memungkinkan pengalaman yang lebih SIMD lebih baik, mungkin suatu hari nanti memenuhi janji SIMD tak kenal takut? Saya ingin berpikir memberikan kontribusi eksplorasi saya untuk diskusi ini, dan benar-benar melihat ke depan untuk melihat di mana ia pergi. Keindahan dan kekuatan dari Rust adalah menyusun komponen-tingkat rendah ke dalam sistem tingkat yang lebih tinggi, menggunakan abstraksi nol-biaya. Saya pasti mendorong orang untuk bereksperimen dengan dan mengeksplorasi berbagai cara penulisan pendekatan SIMD code.The untuk pembungkus newtype dengan aman mengkodekan kedua jenis SIMD dan terdeteksi kemampuan SIMD adalah karena burntsushi dan digunakan untuk efek yang baik dalam peti pencarian cepat tali nya. (source)