1 bình luận

 
GN⁺ 2023-12-04
Ý kiến trên Hacker News
  • Nhìn vào lịch sử các thế hệ ARM mà Raspberry Pi từng dùng thì thật bất ngờ vì đây là một con chip rất cũ
    Ngay cả vào thời điểm Raspberry Pi B+ ra mắt năm 2014, nhân ARM1176 được dùng cũng là thiết kế từ năm 2003, tức đã 11 năm tuổi
    Vì vậy, khi build trên nền tảng khác như Raspberry Pi đời mới hơn, việc có thể cần chỉ định cờ kiến trúc để tạo mã tương thích cũng không có gì lạ
    Tuy nhiên, nếu ngay cả khi build trên chính Raspberry Pi B+ mà kiến trúc đúng cũng không được chọn làm mặc định, thì trông giống như lỗi cấu hình ở phía giá trị mặc định của bản phân phối

    • Tôi nhớ Pi đời đầu dùng chip còn dư từ các hộp TV
      Những sản phẩm như vậy vì lý do giá thành nên hiếm khi nhét nhiều năng lực tính toán hơn mức cần thiết
    • Ngay từ đầu nó đã là sản phẩm định làm thành máy tính giá rẻ
    • Thực ra không phải build trên B+
      Bài viết nói rằng “tôi lấy binary từ host build là Pi 4B nhanh hơn nhiều rồi thử chạy trên thiết bị cũ này thì gặp illegal instruction”
      Việc này giống như cố chạy một file .EXE build bằng MSVC mới nhất trên Windows 11 ở một PC cũ cài Windows XP
      Có lẽ toàn bộ bản phân phối Pi chạy trên Pi 4B cũng nhiều khả năng không chạy được trên B+, và cả kernel cũng có thể đã được biên dịch theo cùng cách
  • Có vẻ bài viết hay bài báo chưa nói rõ, nhưng đây chẳng phải là bug sao?
    Tôi tìm bug của LLVM thì thấy có một mục trông gần như cùng vấn đề, nhưng đó là bug từ năm 2012 và đã bị đóng. Nhìn vài bình luận cuối thì có vẻ thực ra có thể vẫn chưa được sửa, nhưng tôi chỉ lướt qua nên cũng có thể hiểu nhầm
    https://github.com/llvm/llvm-project/issues/13989
    Xem lại thì cuối bài có nói rằng nếu truyền đích một cách tường minh thì sẽ tạo ra chương trình chạy được. Vậy có vẻ giống một dạng lỗi cấu hình, và trên Unix tôi nghĩ đích mặc định sẽ là bộ xử lý hiện tại, nhưng không chắc
    Bug được liên kết có vẻ là vấn đề vẫn tạo mã sai dù đã đặt đúng đích, và may là hiện giờ dường như không phải tình huống đó

    • Đúng vậy. Bug được liên kết là vấn đề dù đã bảo compiler nhắm tới armv6 nhưng nó vẫn phát ra lệnh armv7
      Vấn đề của Rachel được giải quyết bằng cách báo cho compiler nhắm tới armv6, nên bug đó có vẻ đã được sửa và là chuyện riêng với vấn đề này
    • Rõ ràng là bug, nhưng tác giả có vẻ thay vì report thì viết một bài blog với tiêu đề hơi câu click rồi kết bằng “quá kỳ lạ”
  • Cơ sở dữ liệu tôi đang làm, ClickHouse, nỗ lực khá nhiều để duy trì khả năng tương thích với phần cứng rất cũ
    Binary ARM tiêu chuẩn yêu cầu Armv8.2 từ năm 2016 và có thể dùng trên các mẫu từ Raspberry Pi 2 trở về sau. Binary x86 chạy trên phần cứng khoảng năm 2010 có SSE4.2 và các lệnh pclmul* để CRC nhanh
    Chúng tôi cũng build binary cho các hệ thống chỉ có Armv8.0 và SSE2, nhưng không kiểm thử bằng CI. Script cài đặt nhanh sẽ tải xuống và giải nén binary phù hợp với host đích
    Nhìn chung tôi thấy việc cân bằng giữa tương thích ngược và tận dụng các tính năng CPU của những thế hệ AArch64 mới là chuyện khó
    https://en.wikipedia.org/wiki/AArch64
    Có nhiều tổ chức với ngân sách eo hẹp đến mức đáng ngạc nhiên, ví dụ các trường đại học ở nước mới nổi hoặc những người dùng theo sở thích không có khả năng nâng cấp phần cứng
    Về mặt kỹ thuật, một điểm khá phiền là các cờ CPU trong /proc/cpuinfo không phải lúc nào cũng tương ứng với cờ -march= truyền cho compiler. Ví dụ chúng xuất hiện khác nhau như "lrcpc" và "rcpc"
    Để làm cho việc này chạy đúng, thực tế phải quản lý hai tập cờ

    • Trong trường hợp như vậy, tôi nghĩ cung cấp nhiều bản build để khách hàng có thể chọn bản gần nhất với kiến trúc của họ sẽ có lợi cho tất cả
  • Vấn đề rất có khả năng là đích cấu hình đã thay đổi trong gói clang-13 hiện tại của bookworm
    Cụ thể, trong bullseye và clang-11, đích mặc định là armv6k-unknown-linux-gnueabihf, còn trong bookworm và clang-13 là arm-unknown-linux-gnueabihf
    Hoặc cũng có thể phía LLVM đã thay đổi giá trị mặc định của cấu hình build đó

  • Có lẽ đây không phải là thay đổi có chủ ý
    Như các bình luận xung quanh đã nhắc đến /etc/env.d/gcc, khá có khả năng đây là cách đọc thông tin từ môi trường
    Triple mặc định có lẽ sẽ là giá trị kiểu arm-unknown-linux nếu clang không tìm thấy hoặc không được truyền thông tin cụ thể hơn, nhưng có vẻ cơ chế cung cấp target cụ thể hơn đã bị hỏng
    Điều này có thể có nghĩa là không có buildbot ARMv6, hoặc cũng có thể là có buildbot nhưng ở đó cấu hình ngầm định vẫn hoạt động tốt
    LLVM là một cross compiler thật sự tốt. Có thể build từ hầu như bất kỳ target nào sang bất kỳ target nào mà không gặp vấn đề lớn
    Clang thì kém hấp dẫn hơn một chút. Nếu nó được build kèm hỗ trợ target và bạn có thể cho nó biết chính xác cần build cho target nào, có lẽ nó sẽ xử lý đúng. Trong bài này, phỏng đoán ban đầu sai, nhưng khi cung cấp thêm thông tin thì nó đã hoạt động đúng
    Tình hình với runtime library còn tệ hơn. Dù đã build cho một target như armv4, bạn vẫn phải tìm libc tương ứng, v.v., và có thể phải cho compiler biết vị trí của các thư viện và header đó; phần này đến nay các chi tiết vẫn chưa rõ ràng

    • Phần lớn distro và compiler trên thực tế đã bỏ hỗ trợ ARMv6 từ vài năm trước
      Tôi từng gặp vấn đề tương tự khi build binary cho một NAS Synology cũ
    • Tại sao Clang lại phải đọc thông tin từ /etc/env.d/gcc?
  • clang/clang++ đọc các target flag và profile từ /etc/env.d/gcc, và việc giữ cho chúng đúng là trách nhiệm của hệ điều hành
    Trên hệ điều hành này, có vẻ phần quản lý đó không được thực hiện đúng
    Chiếc Gentoo ARM SBC của tôi dựa trên kiến trúc armv4 còn cũ hơn vẫn chạy ổn với các bản cập nhật gcc/clang mới nhất
    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.dthư mục riêng của Gentoo dùng để định nghĩa các biến môi trường mặc định cho phiên người dùng
      Clang không có tính năng đọc thư mục đó, nên không nên giả định rằng các distro khác cũng có nó
      Chỉ là cấu hình compiler của Gentoo đọc biến môi trường CTARGET để chọn target, và Gentoo dùng /etc/env.d để thiết lập giá trị đó
  • Bài viết không nói rõ đó là Debian hay Raspbian, và nếu là Debian thì là port armel hay armhf
    Nếu không có thông tin đó thì việc tranh luận LLVM biên dịch cho tập lệnh nào cũng không có nhiều ý nghĩa. Đó là vấn đề phụ thuộc vào thiết lập target native của LLVM
    Nhân tiện, llvm-toolchaim-snapshot của Debian vẫn hỗ trợ armel, vốn lấy ARMv5T làm baseline. Tuy nhiên hiện có một lỗi riêng trong thư viện OpenMP của LLVM khiến build không thành công

    • Điểm kỳ lạ là bản thân binary Clang được biên dịch với tập lệnh tương thích với Pi B+, nhưng lại không nhắm đến tập lệnh tương thích với Pi B+
      Điều này thật sự lạ. Vì không phải là bảo dùng nó như một cross compiler, nên về lý thuyết host và target phải giống nhau
      Có lẽ image đó là Raspbian. Có vẻ không có lý do gì để không giả định như vậy
  • Có lẽ sẽ hữu ích nếu biết output của lệnh dpkg-architecture và nội dung file /etc/os-release
    Không có những thứ đó thì khó đưa ra bình luận hữu ích

  • Tiêu đề tiếc là hơi giật gân
    Đây là thay đổi target mặc định, và clang vẫn có thể build binary cho Pi B+
    Chỉ cần chỉ định rõ kiến trúc là được. Vì vậy có lẽ nên sửa tiêu đề một chút để thể hiện rõ hơn rằng đây là thay đổi cấu hình mặc định

    • Nếu build ngay trên chính target machine mà vẫn không tạo được binary cho target machine đó, thì tôi không thấy nó giật gân đến mức ấy
  • Thật thú vị vì có vẻ khi debug lý do một chương trình không chạy trên ARM, có thể tiếp cận đại khái theo cách này
    Tôi có một bản build Unity Linux không chạy được trong container; ngay cả khi truyền flag amd64 khi chạy Docker, Unity mono vẫn cố gọi một system call không dùng được
    Tôi đã tìm được cách обход qua nên chưa debug tiếp. Tôi bật development mode và đổi thiết lập build để không dùng mono
    Một ngày nào đó tôi nên đào lại để học thêm