BerandaComputers and TechnologyMempercepat AI dengan Instruksi Vektor

Mempercepat AI dengan Instruksi Vektor

Pencarian sedang dilakukan di seluruh industri untuk menemukan cara terbaik untuk mempercepat aplikasi pembelajaran mesin, dan mengoptimalkan perangkat keras untuk instruksi vektor mendapatkan daya tarik sebagai elemen kunci dalam upaya tersebut.

Instruksi vektor adalah kelas instruksi yang memungkinkan pemrosesan paralel dari kumpulan data. Seluruh array bilangan bulat atau angka floating point diproses dalam satu operasi, menghilangkan mekanisme kontrol loop yang biasanya ditemukan dalam array pemrosesan. Itu, pada gilirannya, meningkatkan kinerja dan efisiensi daya.

Konsep ini bekerja sangat baik dengan operasi matriks renggang yang digunakan untuk kumpulan data tersebut, yang dapat mencapai peningkatan kinerja yang substansial dengan vektorisasi, kata Shubhodeep Roy Choudhury, CEO di Valtrix Systems.

Namun, ini lebih sulit daripada yang mungkin terlihat. Ada masalah desain yang melibatkan perpindahan data masuk dan keluar dari memori dan prosesor, dan ada tantangan verifikasi karena meningkatnya kompleksitas dan ukuran keseluruhan kumpulan data. Namun demikian, permintaan untuk peningkatan kinerja / kekuatan semacam ini melonjak karena jumlah data meningkat, dan instruksi vektor adalah bagian penting dari teka-teki.

“Meskipun Nvidia melakukan pekerjaan yang hebat dalam menjalankan aplikasi ini pada GPU mereka, mereka sangat mahal, sangat haus daya, dan tidak benar-benar ditargetkan,” kata Simon Davidmann, CEO Imperas. “Sekarang, tim teknik sedang membangun perangkat keras khusus, yang akan menjalankan kerangka kerja AI ini dengan cepat. Pengembang melihat vektor untuk menjalankan algoritme pembelajaran mesin dengan cepat. ”

Petunjuk atau ekstensi vektor bukanlah hal baru. Faktanya, mereka adalah bagian penting dari arsitektur CPU modern, dan digunakan dalam beban kerja mulai dari pemrosesan gambar hingga simulasi ilmiah. Intel, Arm, ARC, MIPS, Tensilica, dan lainnya telah membuka jalan bagi pendatang baru seperti RISC-V ISA. Yang berubah adalah meningkatnya spesialisasi dan pengoptimalan keduanya.

Arm pertama kali memperoleh dukungan untuk vektor gaya SIMD lebar tetap di Armv6, yang dengan cepat berkembang menjadi Neon di Armv7-A, menurut Martin Weidmann, direktur manajemen produk di Arm’s Architecture and Technology Group. Baru-baru ini, Arm memperkenalkan Scalable Vector Extensions (SVE), dengan dukungan untuk variabel panjang dan predikat vektor. SVE telah mengalami adopsi, termasuk dalam superkomputer tercepat di dunia .

Arsitektur CPU, seperti arsitektur Arm, pada dasarnya adalah kontrak antara perangkat keras dan perangkat lunak. “Arsitektur menggambarkan perilaku apa yang harus disediakan oleh perangkat keras, dan perangkat lunak dapat diandalkan,” Weidmann menjelaskan. “Yang terpenting dari ini adalah perilaku yang konsisten. Pengembang harus yakin bahwa perangkat apa pun yang mengimplementasikan arsitektur tersebut akan memberikan perilaku yang sama. ”

Misalnya, developer harus yakin bahwa untuk kode apa pun yang berjalan pada desain berbasis Arm, mereka akan melihat perilaku yang dijelaskan dalam Manual Referensi Arsitektur Arm. Sampai titik ini, Arm menciptakan sumber daya pengujian kepatuhan.

Menulis rangkaian kepatuhan yang komprehensif untuk sesuatu yang serbaguna seperti CPU modern selalu menjadi tantangan, kata Weidmann. Ekstensi vektor hanya menambah tantangan itu, terutama di area berikut:

  • Pengujian agnostik panjang vektor (VLA) untuk SVE dan SVE2;
  • Berurusan dengan dependensi yang diperkenalkan oleh pemrosesan bersamaan dari beberapa elemen, termasuk penanganan pengecualian dan ketepatan floating-point, dan
  • Kompleksitas operasi pemuatan dan penyimpanan yang tersebar-berkumpul.

Ara. 1: Contoh bagaimana vektor yang lebih panjang dapat diproses secara paralel. Sumber: Lengan

Graham Wilson, manajer pemasaran produk untuk prosesor ARC di Synopsys, menunjukkan bahwa tim teknik menggunakan kombinasi kemampuan pemrosesan, memasangkan kode yang secara tradisional akan berjalan pada inti pengontrol dengan kode yang akan berjalan di DSP. Semua itu sekarang digabungkan ke dalam komputasi yang dilakukan pada prosesor terpadu.

“Kami melihat lebih banyak DSP vektor tradisional yang telah mengambil lebih banyak peran skalar, atau kemampuan untuk memiliki lebih banyak kode kontrol, karena banyak dari ini didorong oleh perangkat yang berjalan di tepi IoT, dan mereka menginginkan komputasi yang lebih kecil dan berdaya rendah. Ada juga rangkaian kode yang lebih luas – dari kode kontrol, kode DSP, hingga kode vektor – dan sekarang ada komputasi algoritme AI yang didorong oleh kebutuhan berukuran kecil dan daya rendah untuk dijalankan pada satu prosesor. Kami melihat tren dari DSP vektor yang lebih tradisional, yang memiliki kontrol komputasi dan operasi yang lebih baik, bersama dengan tren dari proses pengontrol normal seperti Arm core dan lainnya, untuk menghitung lebih banyak kode vektor. Ekstensi vektor adalah jalur untuk proses pengontrol dasar yang memungkinkannya untuk mengoperasikan dan menjalankan operasi vektor, bersama dengan kode vektor pada inti pengontrol tunggal. “

Desainer SoC mendapatkan manfaat ini secara gratis, karena terdapat di dalam CPU. “Biasanya tidak langsung menyentuh bagian luarnya, jadi dari sudut pandang perancang perangkat keras, jika mereka termasuk CPU yang kebetulan memiliki ekstensi vektor atau tidak, pada dasarnya sama saja bagi mereka,” kata Russell Klein, platform HLS direktur program di Mentor, Bisnis Siemens.

Perancang perangkat lunaklah yang akan perlu memanfaatkan ini dan harus khawatir tentang cara memprogram ekstensi vektor tersebut, kata Klein. “Itu selalu menjadi tantangan. Dalam bahasa pemrograman C tradisional – dan C ++ yang digunakan orang-orang untuk menulis program yang berjalan pada CPU ini – tidak ada pemetaan langsung dari beberapa konstruksi C tertentu ke dalam penggunaan ekstensi vektor. Biasanya, ada sejumlah cara berbeda yang akhirnya Anda dapat mengakses fitur-fitur ini. Daripada menulis dan kode C, yang paling dasar adalah menulis dalam bahasa assembly, dan kemudian Anda dapat memanggil instruksi vektor secara langsung. Kebanyakan orang tidak suka melakukannya karena itu banyak pekerjaan dan tidak menyatu dengan baik dengan kode C yang mereka gunakan di tempat lain. ”

Untuk mengatasi ini, perusahaan prosesor seperti Arm dan Intel telah menulis pustaka untuk memanfaatkan instruksi vektor ini, dan menyediakan pustaka untuk melakukan transformasi Fourier cepat, atau operasi perkalian matriks. “Mereka telah melanjutkan dan mengkodekan semuanya dalam bahasa assembly untuk memanfaatkan operasi pemrosesan vektor tersebut dengan cara yang diinginkan oleh perancang CPU,” jelasnya. “Kemudian pengguna yang menulis sebuah program hanya memanggil FFT khusus atau perkalian matriks, dan ia menggunakan itu. Ini adalah cara mudah bagi Intel dan Arm untuk menyebarkannya, dan saya berharap komunitas RISC-V melakukan hal yang sama. Holy Grail adalah membuat compiler C Anda cukup pintar untuk melihat loop Anda dan memahami bahwa ini dapat di-vectorisasi. “

Ini adalah masalah sulit yang belum terpecahkan di masa lalu, meskipun pekerjaan sedang dilakukan oleh team building LLVM , yang mengklaim bahwa mereka mampu mengenali loop yang dapat di-vector dan memanggil instruksi vektor, kata Klein.

Masalah integrasi
Pertimbangan penting lainnya adalah bagaimana unit vektor harus diintegrasikan ke dalam inti, apakah itu terkait erat atau merupakan unit independen.

“Jika Anda melihat tim yang sudah mengerjakannya, hampir semuanya memutuskan untuk menggunakan unit vektor terpisah yang terhubung ke pipa utama, seperti pada tahap eksekusi,” kata Zdenek Prikryl, CTO dari Codasip. “Dan kemudian, pada dasarnya, Anda dapat menjalankan operasi dalam unit vektor secara terpisah. Anda tidak perlu menghentikan pipeline utama kecuali jika ada ketergantungan. Ini adalah sesuatu yang kami targetkan – untuk memiliki mesin independen yang berkomunikasi atau terhubung erat dengan inti utama, tetapi tidak di dalam pipa inti utama. Pada awalnya, harus ada semacam isyarat untuk instruksi seperti multiply-akumulasi, atau mungkin untuk aliran dan bilangan bulat untuk memuat dan menyimpan, dan sebagainya. Dan pada akhirnya, kami memiliki beberapa jenis tahapan umum di mana Anda dapat meletakkan data yang terikat untuk mendaftarkan file. Juga ingatlah subsistem memori, karena jika Anda memiliki mesin vektor, ada banyak sekali data yang harus Anda proses. Jadi, subsistem memori juga merupakan poin penting – bahkan mungkin menjadi perhatian yang lebih besar karena Anda harus dapat memberi makan mesin dan, pada saat yang sama, mengambil datanya. ”

Throughput tinggi sangat penting untuk mesin vektor, sehingga antarmuka lebar seperti 512 bit, dan memori yang digabungkan erat (TCM) yang dapat menyediakan data secara cepat menjadi optimal. “Ini pertanyaan utama yang harus kami tanyakan di awal desain,” kata Prikryl. “Itu diperlukan untuk membuat arsitektur dengan cara yang tidak diblokir oleh subsistem memori, dan tidak diblokir oleh pipeline bagian skalar utama, sehingga vektor dapat menghasilkan keluaran, dapat bekerja dengan memori, dan meminta inti utama hanya jika perlu untuk berkomunikasi. “

Mesin vektor RISC-V memungkinkan pemilihan lebar register. “Jika Anda menargetkan sistem yang lebih kecil, itu bisa lebih kecil,” kata Prikryl. “Jika Anda menargetkan binatang server besar, maka Anda memiliki register yang sangat luas dan pada dasarnya Anda harus mengikat bandwidth memori dengan register ini. Kemudian Anda dibatasi oleh ini, jadi seberapa luas Anda menargetkan throughput? Biasanya Anda harus hidup dengan standar yang ada di luar sana, seperti standar Amba. Dan kemudian ada beberapa batasan, seperti paling banyak 1.024 bit. Namun pada saat yang sama, jika Anda menargetkan antarmuka yang begitu luas, Anda biasanya mengalami latensi atau frekuensi karena cukup lebar. Jadi ada semacam kompromi. Kami ingin memberikan data yang cepat dari TCM agar dapat memasukkan data dengan cukup cepat. Pada saat yang sama, kita harus memikirkan model pemrograman dalam kasus subsistem memori. Saya juga ingin kemungkinan memuat data melalui cache standar karena model pemrogramannya lebih mudah. Jika Anda menulis kode C, maka pada akhirnya Anda dapat menyimpan vektor, tidak hanya ke vektor dalam memori, tetapi juga ke memori cache. Dan kemudian, dengan bagian skalar Anda dapat menyentuh vektor dan mengubah berbagai hal di sana-sini. ”

Pertimbangan lain adalah harus ada cara untuk memberi makan mesin. Mesin harus dapat berkomunikasi dengan bagian skalar untuk subsistem memori cache standar, dan harus dirancang dengan cara ini. “Kita harus menyeimbangkan model pemrograman dengan cara pengguna dapat memprogram pada mesin,” katanya. “Seharusnya semudah mungkin, artinya kita harus memberikan instruksi bagaimana melakukan vektorisasi. Kita harus memberi mereka manipulasi tumpukan, dan hal-hal semacam ini. Ini biasanya dilakukan melalui kombinasi memori utama dan TCM. Ini bukan hanya TCM yang harus Anda muat datanya terlebih dahulu. Kedua dunia ini dapat digabungkan sehingga mudah untuk diprogram, lalu saya dapat memasukkannya melalui TCM dan saya masih dapat memberikan data di sana. Tetapi jika saya perlu memiliki sesuatu yang bukan merupakan bagian penting dari mesin, itu dapat berfungsi di cache. Tidak harus pergi ke TCM. Dengan cara ini, subsistem memori bisa jadi rumit. “

Klein dari Mentor mencatat bahwa salah satu area yang menjadi perhatian adalah subsistem memori yang terkait dengan register. “Anda harus bisa memasukkan data ke register ini untuk melakukan operasi, dan kemudian Anda perlu mendapatkan kembali hasilnya,” katanya. “Misalnya, pada inti Arm Anda dapat memiliki register dengan lebar hingga 2.048 bit. Jika lebar bus yang keluar ke memori adalah 128 bit, yang akan terjadi sangat cepat adalah unit pemroses vektor akan kekurangan data karena Anda tidak akan dapat menariknya dari memori utama dengan cukup cepat. Kemudian Anda juga ingin melihat jalur dari cache ke dalam CPU. Itu bisa lebih luas daripada jalur keluar ke memori utama, karena pada dasarnya tidak terlalu sulit untuk membangun unit pemroses vektor yang akan menghabiskan lebih banyak bandwidth daripada yang tersedia di dalam dan di luar memori utama. Jika demikian, mesinnya telah direkayasa secara berlebihan dan Anda tidak dapat memperoleh cukup data untuk itu dengan cukup cepat atau menghabiskan hasilnya dengan cukup cepat untuk benar-benar memanfaatkan akselerasi yang tersedia di sana. ”

Selain itu, saat beralih dari pengontrol dengan subsistem memori terpadu ke pengontrol dengan operasi vektor, data perlu diselaraskan dan dikemas. Pekerjaan vektor semacam itu mengumpulkan semua data ini, dan kemudian menjalankannya pada operasi SIMD tunggal (instruksi tunggal, banyak data). Karena itu, ruang di dalam memori perlu dikemas sebelumnya dan dialokasikan sebelumnya.

“Anda juga harus bisa membawa data itu,” kata Synopsys ‘Wilson. “Terkadang data ini, jika Anda menggunakan panjang vektor yang panjang, juga cukup panjang, dan biasanya lebih lama dari memori sistem tujuan umum yang mungkin Anda miliki. Jadi, Anda perlu memperluas, atau beberapa DSP tradisional mungkin menggunakan arsitektur penyimpanan beban memori khusus untuk menyambung ke memori data vektor ini. Itu memungkinkan Anda untuk memasukkan ini secara efisien, menghitung, dan kemudian mengirimkannya kembali. “

Memverifikasi vektor
Verifikasi ekstensi instruksi vektor dan mesin vektor umumnya tidak terlalu berbeda dengan instruksi skalar.

“Anda perlu memverifikasi prosesor ini seperti yang lain,” kata Darko Tomusilovic, manajer verifikasi di Vtool. “Anda perlu memahami apa yang dilakukan setiap instruksi, bagaimana memodelkannya di lingkungan Anda, bagaimana melakukan pramuat baik serangkaian instruksi acak untuk menstimulasinya, atau menulis perangkat lunak yang tepat, yang akan dikompilasi menjadi kode yang Anda jalankan. Selain itu, ini adalah proses klasik seperti verifikasi prosesor lainnya. Ini, tentu saja, lebih kompleks untuk memodelkan instruksi seperti itu, tetapi dalam hal alur kerja, ini persis sama. ”

Roy Choudhury setuju. “Pendekatan verifikasi instruksi vektor tidak terlalu berbeda dengan instruksi skalar. Prosesnya harus dimulai dengan rangkaian pengujian yang komprehensif, yang dapat menjelajahi pengaturan konfigurasi untuk semua instruksi dan membandingkan hasil pengujian dengan referensi emas. Setelah jalur konfigurasi dihapus, fokus harus beralih ke pengujian acak dan interoperabilitas terbatas. Kasus penggunaan vektorisasi juga perlu dicakup untuk memastikan bahwa beban kerja dan aplikasi berjalan lancar. “

Pada saat yang sama, ada beberapa pertimbangan verifikasi terkait vektor, kata Roy Choudhury. “Karena instruksi vektor beroperasi dengan data dalam jumlah besar, status prosesor secara keseluruhan yang diamati untuk pengujian apa pun sangat besar. Beberapa implementasi vektor, seperti RISC-V, dirancang agar sangat fleksibel, memungkinkan pengguna untuk mengonfigurasi ukuran elemen, elemen awal, ukuran grup register vektor, dll. Jadi, jumlah konfigurasi yang harus diperiksa setiap instruksi sangat besar. . Faktor-faktor ini menambah kompleksitas verifikasi. “

Dengan kata lain, verifikasi perlu bergeser ke kiri. “Teknik perangkat lunak pengujian dan integrasi berkelanjutan diadopsi oleh SoC perangkat keras dan tim desain prosesor,” kata Imperas ‘Davidmann. Perkiraan yang sering dikutip bahwa 60% sampai 80% dari biaya dan waktu proyek desain untuk verifikasi adalah penyederhanaan yang berlebihan. Desain adalah verifikasi. Saat tim desain mengembangkan spesifikasi fungsional, rencana pengujian menjadi inti dari semua diskusi. Verifikasi tidak lagi hanya menjadi tonggak sejarah di akhir fase desain. Dengan standar terbuka ISA RISC-V, spesifikasi memungkinkan banyak opsi dan konfigurasi selain ekstensi khusus. Saat perancang memilih dan menentukan fitur yang diperlukan, rencana pengujian terperinci diperlukan untuk dikembangkan bersama di setiap negara bagian. Co-design sebenarnya adalah perangkat keras, perangkat lunak, dan verifikasi sebagai proses simultan yang berkelanjutan. “

Kesimpulan
Selain semua tantangan desain dan verifikasi, salah satu kunci untuk mendesain instruksi vektor adalah memahami aplikasi akhir yang ditargetkan.

“Pada akhirnya, Anda menggunakan mesin vektor karena Anda melakukan semacam pemrosesan sinyal atau semacam pemrosesan gambar, atau lebih sering hari ini, menyimpulkan,” kata Klein. “Alasan kami banyak mendengar tentang ini adalah karena perkembangan algoritme pembelajaran mesin. Di sana, operasi multi-akumulasi sedang dilakukan pada array besar. Ini benar-benar berulang, ada banyak data, dan cocok untuk matematika vektor ini. Misalkan Anda menggunakan algoritme kesimpulan untuk melihat ukuran yang diharapkan dari peta fitur kernel konvolusi Anda, dan bagaimana kesesuaiannya dengan unit vektor yang Anda rencanakan untuk dibuat. Jika Anda memiliki kernel konvolusi yang terdiri dari 9 elemen 8 bit, memasukkan unit pengolah vektor yang akan menjadi 1.024 bit tidak akan membantu karena Anda hanya mendapatkan 72 bit data kernel yang Anda miliki. membawa ke dalam campuran. Dengan cara ini, memahami aplikasi akhir dan dengan mempertimbangkan pola data dan pola komputasi yang perlu Anda dukung adalah cara untuk mendapatkan campuran yang tepat antara akselerator dan bandwidth I / O dan desain total yang akan efisien. memenuhi aplikasi yang Anda cari. “

Read More

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments