Kalau melihat sejarah generasi ARM yang dipakai Raspberry Pi, mengejutkan betapa tuanya chip itu
Bahkan pada 2014, saat Raspberry Pi B+ dirilis, core ARM1176 yang dipakai berasal dari 2003, jadi saat itu sudah berusia 11 tahun
Jadi tidak aneh kalau saat membangun di platform lain seperti Raspberry Pi yang lebih baru, kita mungkin perlu menetapkan flag arsitektur agar menghasilkan kode yang kompatibel
Namun jika arsitektur yang benar tidak menjadi default bahkan saat membangun di Raspberry Pi B+ itu sendiri, itu terlihat seperti kesalahan konfigurasi pada default distribusi
Seingat saya, Pi asli memakai chip sisa yang sebelumnya digunakan untuk TV box
Produk seperti itu hampir tidak pernah memasukkan performa komputasi lebih dari yang diperlukan karena alasan harga
Dari awal memang produk itu dimaksudkan sebagai komputer murah
Sebenarnya bukan dibangun di B+
Di tulisannya disebutkan bahwa “saya mengambil binary dari build host berupa Pi 4B yang jauh lebih cepat, lalu mencoba menjalankannya di perangkat tua ini, dan mendapat illegal instruction”
Ini mirip seperti mencoba menjalankan .EXE yang dibangun dengan MSVC terbaru di Windows 11 pada PC lama yang menjalankan Windows XP
Kemungkinan besar seluruh distribusi Pi yang berjalan di Pi 4B juga tidak akan berjalan di B+, dan kernel-nya pun bisa saja dikompilasi dengan cara yang sama
Rasanya ini tidak dibahas dengan jelas di tulisan atau artikelnya, tetapi bukankah ini bug?
Saat mencari bug LLVM, saya menemukan tiket yang terlihat hampir sama, tetapi itu bug dari 2012 dan sudah ditutup. Dari beberapa komentar terakhir, tampaknya mungkin sebenarnya belum diperbaiki, tetapi saya hanya membaca sekilas jadi bisa saja salah paham https://github.com/llvm/llvm-project/issues/13989
Setelah saya lihat lagi, di akhir tulisan disebutkan bahwa jika target diberikan secara eksplisit, program yang dihasilkan bisa berjalan. Kalau begitu ini tampaknya semacam bug konfigurasi, dan di Unix saya mengira target default adalah prosesor saat ini, tetapi saya tidak yakin
Bug yang saya tautkan sepertinya masalah ketika target sudah disetel dengan benar tetapi tetap menghasilkan kode yang salah, dan untungnya sekarang tampaknya bukan situasi seperti itu
Benar. Bug yang ditautkan itu adalah masalah ketika compiler diminta menargetkan armv6 tetapi tetap mengeluarkan instruksi armv7
Masalah Rachel terselesaikan dengan memberi tahu compiler agar menargetkan armv6, jadi bug itu tampaknya sudah diperbaiki dan terlihat terpisah dari masalah ini
Jelas itu bug, tetapi penulisnya tampaknya memilih menulis posting blog dengan judul yang agak memancing klik dan mengakhirinya dengan “ini terlalu aneh”, alih-alih melaporkannya
ClickHouse, database tempat saya bekerja, berusaha cukup keras untuk menjaga kompatibilitas dengan hardware yang sangat lama
Binary ARM standar membutuhkan Armv8.2 dari 2016, dan bisa digunakan pada model Raspberry Pi 2 dan setelahnya. Binary x86 berjalan pada hardware sekitar 2010 yang memiliki SSE4.2 dan instruksi pclmul* untuk CRC cepat
Kami juga membangun binary untuk sistem yang hanya memiliki Armv8.0 dan SSE2, tetapi tidak mengujinya dengan CI. Skrip instalasi cepat akan mengunduh dan mengekstrak binary yang sesuai untuk host target
Secara umum, saya merasa sulit menyeimbangkan antara kompatibilitas ke belakang dan pemanfaatan fitur CPU pada generasi AArch64 terbaru https://en.wikipedia.org/wiki/AArch64
Ada sangat banyak institusi dengan anggaran ketat, misalnya universitas di negara berkembang, atau pengguna hobi yang tidak punya kemampuan untuk upgrade hardware
Secara teknis, cukup merepotkan bahwa flag CPU di /proc/cpuinfo tidak selalu sesuai dengan flag -march= yang diteruskan ke compiler. Misalnya, muncul berbeda seperti "lrcpc" dan "rcpc"
Agar ini berjalan dengan benar, pada dasarnya perlu mengelola dua set flag
Dalam kasus seperti itu, saya rasa menyediakan beberapa build agar pelanggan bisa memilih yang paling dekat dengan arsitektur mereka akan menguntungkan semua pihak
Masalahnya kemungkinan besar adalah target konfigurasi berubah pada paket clang-13 saat ini di bookworm
Secara spesifik, di bullseye dan clang-11 target default-nya adalah armv6k-unknown-linux-gnueabihf, sedangkan di bookworm dan clang-13 menjadi arm-unknown-linux-gnueabihf
Atau bisa juga default untuk konfigurasi build tersebut berubah di sisi LLVM
Sepertinya ini bukan perubahan yang disengaja
Seperti disebutkan di komentar sekitar tentang /etc/env.d/gcc, kemungkinan besar ini terkait cara membaca informasi dari environment
Triple default kemungkinan nilainya seperti arm-unknown-linux jika clang tidak menemukan atau tidak diberi informasi yang lebih spesifik, dan tampaknya mekanisme yang memberi tahu target yang lebih spesifik itu rusak
Ini bisa berarti tidak ada buildbot ARMv6, atau buildbot-nya ada tetapi di sana konfigurasi implisitnya masih bekerja dengan baik
LLVM adalah cross compiler yang benar-benar bagus. Dari target apa pun ke target apa pun, umumnya bisa build tanpa masalah besar
Clang sedikit kurang menarik dibanding itu. Jika dibangun dengan dukungan target dan kita bisa memberi tahu dengan benar target mana yang akan dibuild, kemungkinan ia akan menanganinya dengan benar. Di tulisan ini pun dugaannya salah, tetapi setelah diberi informasi tambahan ia bekerja dengan benar
Situasi runtime library lebih buruk. Meski dibuild untuk target seperti armv4, tetap harus menemukan libc dan semacamnya yang sesuai, dan mungkin harus memberi tahu compiler lokasi library dan header tersebut; detail di bagian ini masih belum jelas
Sebagian besar distro dan compiler pada dasarnya sudah melepas dukungan ARMv6 beberapa tahun lalu
Saya pernah mengalami masalah serupa saat membuild binary untuk Synology NAS lama
Mengapa Clang harus membaca informasi dari /etc/env.d/gcc?
clang/clang++ membaca flag target dan profil dari /etc/env.d/gcc, dan menjaganya tetap benar adalah tanggung jawab sistem operasi
Di sistem operasi ini, pengelolaannya tampaknya tidak berjalan dengan benar
Gentoo ARM SBC saya yang berbasis arsitektur armv4 yang lebih lama tetap berjalan baik dengan update gcc/clang terbaru grep CTARGET /etc/env.d/gcc -r /etc/env.d/gcc/armv4tl-softfloat-linux-gnueabi-11.3.0:CTARGET="armv4tl-softfloat-linux-gnueabi"
/etc/env.d adalah direktori khusus Gentoo yang mendefinisikan environment variable default untuk sesi pengguna
Clang tidak punya fitur untuk membaca direktori itu, jadi jangan berasumsi bahwa direktori itu juga ada di distro lain
Yang terjadi hanya konfigurasi compiler Gentoo membaca environment variable CTARGET untuk memilih target, dan Gentoo menggunakan /etc/env.d untuk mengatur nilai tersebut
Tulisan itu tidak menyebutkan apakah ini Debian atau Raspbian, dan jika Debian, apakah port armel atau armhf
Tanpa informasi itu, tidak banyak gunanya memperdebatkan LLVM mengompilasi untuk instruction set apa. Itu bergantung pada konfigurasi target native LLVM
Sebagai catatan, llvm-toolchaim-snapshot milik Debian masih mendukung armel yang memakai ARMv5T sebagai baseline. Namun saat ini ada bug terpisah di library OpenMP LLVM, sehingga build-nya tidak berhasil
Yang aneh adalah binary Clang itu sendiri dikompilasi dengan instruction set yang kompatibel dengan Pi B+, tetapi justru tidak menargetkan instruction set yang kompatibel dengan Pi B+
Ini benar-benar aneh. Karena tidak dimaksudkan untuk dipakai sebagai cross compiler, secara teori host dan target seharusnya sama
Kemungkinan image-nya adalah Raspbian. Rasanya tidak ada alasan untuk tidak mengasumsikan begitu
Akan membantu jika mengetahui output perintah dpkg-architecture dan isi file /etc/os-release
Tanpa itu, sulit memberi komentar yang berguna
Judulnya sayangnya agak sensasional
Ini adalah perubahan target default, dan clang masih bisa membuild binary untuk Pi B+
Cukup tentukan arsitekturnya secara eksplisit. Jadi sepertinya lebih baik judulnya sedikit diubah agar lebih jelas bahwa ini adalah perubahan konfigurasi default
Kalau membuild langsung di mesin target tetapi tetap tidak bisa membuat binary untuk mesin target itu, rasanya tidak terlalu sensasional
Menarik karena sepertinya saat men-debug mengapa program tidak berjalan di ARM, pendekatannya kira-kira seperti ini
Ada build Unity Linux yang tidak berjalan di dalam container; meski flag amd64 diberikan saat menjalankan Docker, Unity mono mencoba melakukan system call yang tidak bisa dipakai
Saya menemukan workaround dan belum men-debug-nya. Saya menyalakan mode pengembangan dan mengubah konfigurasi build agar tidak memakai mono
Suatu saat saya harus menggali lagi untuk belajar lebih banyak
1 komentar
Komentar Hacker News
Kalau melihat sejarah generasi ARM yang dipakai Raspberry Pi, mengejutkan betapa tuanya chip itu
Bahkan pada 2014, saat Raspberry Pi B+ dirilis, core ARM1176 yang dipakai berasal dari 2003, jadi saat itu sudah berusia 11 tahun
Jadi tidak aneh kalau saat membangun di platform lain seperti Raspberry Pi yang lebih baru, kita mungkin perlu menetapkan flag arsitektur agar menghasilkan kode yang kompatibel
Namun jika arsitektur yang benar tidak menjadi default bahkan saat membangun di Raspberry Pi B+ itu sendiri, itu terlihat seperti kesalahan konfigurasi pada default distribusi
Produk seperti itu hampir tidak pernah memasukkan performa komputasi lebih dari yang diperlukan karena alasan harga
Di tulisannya disebutkan bahwa “saya mengambil binary dari build host berupa Pi 4B yang jauh lebih cepat, lalu mencoba menjalankannya di perangkat tua ini, dan mendapat illegal instruction”
Ini mirip seperti mencoba menjalankan .EXE yang dibangun dengan MSVC terbaru di Windows 11 pada PC lama yang menjalankan Windows XP
Kemungkinan besar seluruh distribusi Pi yang berjalan di Pi 4B juga tidak akan berjalan di B+, dan kernel-nya pun bisa saja dikompilasi dengan cara yang sama
Rasanya ini tidak dibahas dengan jelas di tulisan atau artikelnya, tetapi bukankah ini bug?
Saat mencari bug LLVM, saya menemukan tiket yang terlihat hampir sama, tetapi itu bug dari 2012 dan sudah ditutup. Dari beberapa komentar terakhir, tampaknya mungkin sebenarnya belum diperbaiki, tetapi saya hanya membaca sekilas jadi bisa saja salah paham
https://github.com/llvm/llvm-project/issues/13989
Setelah saya lihat lagi, di akhir tulisan disebutkan bahwa jika target diberikan secara eksplisit, program yang dihasilkan bisa berjalan. Kalau begitu ini tampaknya semacam bug konfigurasi, dan di Unix saya mengira target default adalah prosesor saat ini, tetapi saya tidak yakin
Bug yang saya tautkan sepertinya masalah ketika target sudah disetel dengan benar tetapi tetap menghasilkan kode yang salah, dan untungnya sekarang tampaknya bukan situasi seperti itu
Masalah Rachel terselesaikan dengan memberi tahu compiler agar menargetkan armv6, jadi bug itu tampaknya sudah diperbaiki dan terlihat terpisah dari masalah ini
ClickHouse, database tempat saya bekerja, berusaha cukup keras untuk menjaga kompatibilitas dengan hardware yang sangat lama
Binary ARM standar membutuhkan Armv8.2 dari 2016, dan bisa digunakan pada model Raspberry Pi 2 dan setelahnya. Binary x86 berjalan pada hardware sekitar 2010 yang memiliki SSE4.2 dan instruksi pclmul* untuk CRC cepat
Kami juga membangun binary untuk sistem yang hanya memiliki Armv8.0 dan SSE2, tetapi tidak mengujinya dengan CI. Skrip instalasi cepat akan mengunduh dan mengekstrak binary yang sesuai untuk host target
Secara umum, saya merasa sulit menyeimbangkan antara kompatibilitas ke belakang dan pemanfaatan fitur CPU pada generasi AArch64 terbaru
https://en.wikipedia.org/wiki/AArch64
Ada sangat banyak institusi dengan anggaran ketat, misalnya universitas di negara berkembang, atau pengguna hobi yang tidak punya kemampuan untuk upgrade hardware
Secara teknis, cukup merepotkan bahwa flag CPU di /proc/cpuinfo tidak selalu sesuai dengan flag -march= yang diteruskan ke compiler. Misalnya, muncul berbeda seperti "lrcpc" dan "rcpc"
Agar ini berjalan dengan benar, pada dasarnya perlu mengelola dua set flag
Masalahnya kemungkinan besar adalah target konfigurasi berubah pada paket clang-13 saat ini di bookworm
Secara spesifik, di bullseye dan clang-11 target default-nya adalah armv6k-unknown-linux-gnueabihf, sedangkan di bookworm dan clang-13 menjadi arm-unknown-linux-gnueabihf
Atau bisa juga default untuk konfigurasi build tersebut berubah di sisi LLVM
Namun jika membandingkan [1] dan [2], ada pengujian yang rapi di file rules yang berbunyi “jika DEB_HOST_ARCH adalah armhf, set LLVM_HOST_TRIPLE ke armv6k”, jadi tampaknya itu mengonfirmasi perubahan konfigurasi build
[1] http://raspbian.raspberrypi.org/raspbian/pool/main/l/llvm-to...
[2] http://raspbian.raspberrypi.org/raspbian/pool/main/l/llvm-to...
Sepertinya ini bukan perubahan yang disengaja
Seperti disebutkan di komentar sekitar tentang /etc/env.d/gcc, kemungkinan besar ini terkait cara membaca informasi dari environment
Triple default kemungkinan nilainya seperti arm-unknown-linux jika clang tidak menemukan atau tidak diberi informasi yang lebih spesifik, dan tampaknya mekanisme yang memberi tahu target yang lebih spesifik itu rusak
Ini bisa berarti tidak ada buildbot ARMv6, atau buildbot-nya ada tetapi di sana konfigurasi implisitnya masih bekerja dengan baik
LLVM adalah cross compiler yang benar-benar bagus. Dari target apa pun ke target apa pun, umumnya bisa build tanpa masalah besar
Clang sedikit kurang menarik dibanding itu. Jika dibangun dengan dukungan target dan kita bisa memberi tahu dengan benar target mana yang akan dibuild, kemungkinan ia akan menanganinya dengan benar. Di tulisan ini pun dugaannya salah, tetapi setelah diberi informasi tambahan ia bekerja dengan benar
Situasi runtime library lebih buruk. Meski dibuild untuk target seperti armv4, tetap harus menemukan libc dan semacamnya yang sesuai, dan mungkin harus memberi tahu compiler lokasi library dan header tersebut; detail di bagian ini masih belum jelas
Saya pernah mengalami masalah serupa saat membuild binary untuk Synology NAS lama
clang/clang++ membaca flag target dan profil dari /etc/env.d/gcc, dan menjaganya tetap benar adalah tanggung jawab sistem operasi
Di sistem operasi ini, pengelolaannya tampaknya tidak berjalan dengan benar
Gentoo ARM SBC saya yang berbasis arsitektur armv4 yang lebih lama tetap berjalan baik dengan update gcc/clang terbaru
grep CTARGET /etc/env.d/gcc -r/etc/env.d/gcc/armv4tl-softfloat-linux-gnueabi-11.3.0:CTARGET="armv4tl-softfloat-linux-gnueabi"Clang tidak punya fitur untuk membaca direktori itu, jadi jangan berasumsi bahwa direktori itu juga ada di distro lain
Yang terjadi hanya konfigurasi compiler Gentoo membaca environment variable CTARGET untuk memilih target, dan Gentoo menggunakan /etc/env.d untuk mengatur nilai tersebut
Tulisan itu tidak menyebutkan apakah ini Debian atau Raspbian, dan jika Debian, apakah port armel atau armhf
Tanpa informasi itu, tidak banyak gunanya memperdebatkan LLVM mengompilasi untuk instruction set apa. Itu bergantung pada konfigurasi target native LLVM
Sebagai catatan, llvm-toolchaim-snapshot milik Debian masih mendukung armel yang memakai ARMv5T sebagai baseline. Namun saat ini ada bug terpisah di library OpenMP LLVM, sehingga build-nya tidak berhasil
Ini benar-benar aneh. Karena tidak dimaksudkan untuk dipakai sebagai cross compiler, secara teori host dan target seharusnya sama
Kemungkinan image-nya adalah Raspbian. Rasanya tidak ada alasan untuk tidak mengasumsikan begitu
Akan membantu jika mengetahui output perintah
dpkg-architecturedan isi file/etc/os-releaseTanpa itu, sulit memberi komentar yang berguna
Judulnya sayangnya agak sensasional
Ini adalah perubahan target default, dan clang masih bisa membuild binary untuk Pi B+
Cukup tentukan arsitekturnya secara eksplisit. Jadi sepertinya lebih baik judulnya sedikit diubah agar lebih jelas bahwa ini adalah perubahan konfigurasi default
Menarik karena sepertinya saat men-debug mengapa program tidak berjalan di ARM, pendekatannya kira-kira seperti ini
Ada build Unity Linux yang tidak berjalan di dalam container; meski flag amd64 diberikan saat menjalankan Docker, Unity mono mencoba melakukan system call yang tidak bisa dipakai
Saya menemukan workaround dan belum men-debug-nya. Saya menyalakan mode pengembangan dan mengubah konfigurasi build agar tidak memakai mono
Suatu saat saya harus menggali lagi untuk belajar lebih banyak