5 điểm bởi GN⁺ 2025-12-29 | 1 bình luận | Chia sẻ qua WhatsApp
  • MacThrottleứng dụng dựa trên SwiftUI hiển thị trực quan trên thanh menu khi Mac giới hạn hiệu năng do quá nhiệt - mã nguồn mở
  • So sánh API ProcessInfo.thermalState của macOS với lệnh powermetrics, đồng thời tìm cách phát hiện chính xác trạng thái nhiệt thực tế của hệ thống
  • Cuối cùng triển khai phương thức tận dụng thông báo mà thermald đăng lên hệ thống notifyd của Darwin để đọc trạng thái nhiệt mà không cần quyền root
  • Ứng dụng bao gồm đồ thị nhiệt độ và tốc độ quạt, biểu tượng màu theo từng trạng thái, tính năng thông báo macOS, đồng thời hỗ trợ tự chạy khi đăng nhập
  • Là công cụ giúp nắm bắt trạng thái quản lý nhiệt của Apple Silicon Mac theo thời gian thực, mang lại phương tiện chẩn đoán hữu ích cho lập trình viên và người dùng nâng cao

Nhận diện vấn đề thermal throttling trên Mac

  • Khi dùng màn hình ngoài 4K 120Hz với M2 MacBook Air, đã xảy ra suy giảm hiệu năng và độ trễ phản hồi
    • Không có quạt nên không thể nhận biết qua tiếng ồn, nhưng mức tiêu thụ điện lại giảm trong khi CPU đang ở 100% tải
  • Dùng iStat Menus và MX Power Gadget để xác nhận xung nhịp CPU và mức điện năng bị sụt giảm, từ đó chẩn đoán thermal throttling
  • Hiện tượng tương tự cũng xuất hiện trên M4 Max MacBook Pro, được nhắc đến như vấn đề do giới hạn thiết kế nhiệt của bản 14 inch
  • Dù hiệu quả điện năng của Apple Silicon vẫn rất cao, tác giả vẫn muốn tìm cách phát hiện trực tiếp trạng thái nhiệt

Kiểm tra trạng thái nhiệt trên macOS bằng lập trình

  • macOS có nhiều cách để lộ trạng thái nhiệt, nhưng thiếu tính nhất quán
  • Cách Apple khuyến nghị là dùng ProcessInfo.thermalState trong Foundation
    • Ví dụ đầu ra: nominal, fair, serious, critical
  • Lệnh powermetrics -s thermal yêu cầu quyền root cũng cung cấp thông tin tương tự, nhưng
    mức phân chia trạng thái của hai cách là khác nhau
    • Ví dụ: fair bao trùm cả hai trạng thái moderateheavy trong powermetrics
  • Thời điểm throttling thực sự xuất hiện được hiển thị là heavy trong powermetrics, nhưng ProcessInfo không thể phân biệt được

Tận dụng thermald và hệ thống thông báo Darwin

  • Dữ liệu của powermetrics đến từ daemon thermald, và
    thermald đăng trạng thái áp lực nhiệt hiện tại dưới dạng sự kiện hệ thống notifyd
  • Có thể kiểm tra trạng thái bằng lệnh notifyutil -g com.apple.system.thermalpressurelevel
  • Các mức áp lực nhiệt được định nghĩa trong header OSThermalNotification.h:
    • nominal, moderate, heavy, trapping, sleeping
  • Bằng cách gọi notify_register_checknotify_get_state trong mã Swift, đã triển khai được chức năng đọc trạng thái nhiệt theo thời gian thực mà không cần quyền root

Phát triển ứng dụng MacThrottle

  • Tạo ứng dụng chỉ dành cho thanh menu bằng SwiftUI và MenuBarExtra
    • Hiển thị trạng thái qua màu biểu tượng nhiệt kế (xanh lá → đỏ)
    • Đặt LSUIElement trong Info.plist thành true để vô hiệu hóa biểu tượng Dock

Cách tiếp cận ban đầu: helper powermetrics chạy bằng root

  • Ban đầu, để dùng powermetrics cần quyền root, tác giả đã
    dựng tiến trình helper bằng LaunchDaemon và script bash
    • /usr/local/bin/mac-throttle-thermal-monitor ghi trạng thái vào tệp /tmp mỗi 10 giây
    • Ứng dụng đọc định kỳ tệp đó để hiển thị

Cải tiến: dùng thông báo IPC của thermald

  • Chuyển sang cách đăng ký trực tiếp sự kiện notifyd
    • Không cần quyền root, mã nguồn cũng đơn giản hơn

Hiển thị nhiệt độ và tốc độ quạt

  • Hiển thị đồ thị nhiệt độ CPU/GPU và tốc độ quạt
  • Ban đầu, khi dùng API riêng tư của IOKit, nhiệt độ hiển thị thấp hơn thực tế (~80°C)
  • Tham khảo dự án mã nguồn mở Stats và chuyển sang dùng giao diện SMC
    • Cần dùng các khóa khác nhau theo từng thế hệ SoC (Tp0D, Tf0E, v.v.)
  • Nếu SMC không hoạt động thì fallback sang IOKit

Triển khai đồ thị trên thanh menu

  • Đồ thị hiển thị đồng thời 3 loại thông tin
    • Màu nền: trạng thái nhiệt (xanh lá ~ đỏ)
    • Đường liền: nhiệt độ CPU
    • Đường đứt: tỷ lệ tốc độ quạt
  • Thu thập dữ liệu mỗi 2 giây, giữ lịch sử trong 10 phút
  • Cung cấp tooltip bằng onContinuousHover, và
    thêm .drawingGroup để dùng GPU rendering, giúp hiển thị mượt ngay cả trên màn hình 120Hz

Thông báo macOS và tự chạy

  • Bổ sung tính năng gửi thông báo khi trạng thái nhiệt thay đổi
    • Có thể thông báo khi chuyển sang trạng thái nhất định hoặc khi phục hồi
  • Hỗ trợ thiết lập tự chạy khi đăng nhập bằng API SMAppService
    • Điều khiển qua các phương thức register() / unregister() / status

Phân phối và sử dụng

  • Do không có tài khoản Apple Developer nên không thể notarization chính thức
    • Khi cài từ GitHub Releases, cần tự phê duyệt trong Privacy and Security
    • Trên một số máy Mac, cần tự build bằng Xcode mới có thể chạy
  • Cách cài đặt và build được ghi trong README trên GitHub

Kết luận

  • MacThrottle là công cụ gọn nhẹ giúp giám sát trạng thái thermal throttling của Apple Silicon Mac theo thời gian thực
  • Hoạt động không cần quyền root, đồng thời mang lại phản hồi trực quan, thông báo và đồ thị, giúp
    lập trình viên và người dùng tác vụ hiệu năng cao nhận biết trạng thái nhiệt của hệ thống

1 bình luận

 
GN⁺ 2025-12-29
Ý kiến trên Hacker News
  • Tôi từng dùng MacBook Pro i9 bản 2019, và có vẻ hàm phát hiện thermal throttling có thể viết đơn giản thế này

    function isThermalThrottling() {
      return true;
    }
    

    Chỉ là đùa thôi, nhưng việc mua một CPU i9 đắt tiền mà hiệu năng lại còn kém hơn i7 thực sự khá thất vọng

    • Tôi cũng dùng đúng mẫu đó, và chỉ cần sạc bằng cổng bên phải là khắc phục được vấn đề
      Tôi cũng không rõ lý do, nhưng làm vậy thì hiện tượng throttling biến mất
      Dù vậy tôi vẫn tiếp tục dùng vì đã quen với quy trình làm việc trên macOSLogic
      Có thể tôi sẽ chuyển sang Linux, nhưng hiện tại nó vẫn là một cỗ máy dùng khá ổn
    • Tôi cũng từng dùng mẫu i9 2019, và khi gắn thermal pad vào mô-đun VRM thì máy như biến thành một chiếc máy tính hoàn toàn mới
      Mỗi lần dùng hai màn hình ngoài cùng Adobe Creative Suite là máy bị throttling rất nặng, nhưng miếng pad này đã giải quyết được
      Nhược điểm là mặt đáy máy nóng lên nên khó để trên đùi, nhưng tôi hoàn toàn không hối hận
      Giờ tôi đã đổi sang M3 MacBook Air (24GB RAM) và rất hài lòng
      Nếu vẫn còn dùng mẫu 2019 thì tôi rất khuyên nên cân nhắc mod thermal pad cho VRM
    • Thực ra tôi nghĩ bản thân i9 vốn là một CPU không phù hợp cho laptop
      Bên Dell cũng cải thiện rõ rệt ngay khi đổi từ i9 sang i7
      Đúng kiểu bị lừa bởi marketing “số to hơn = CPU tốt hơn”
    • Tôi cũng gặp đúng vấn đề này, đặc biệt là khi cắm hai màn hình ngoài
      Sau đó tôi chuyển sang M1 Max và đúng là như sang một thế giới khác
      Giờ tôi đã nâng cấp lên M3 Max, và Apple Silicon có vẻ sẽ còn trụ được lâu
    • Chiếc laptop đó là máy tính tệ nhất mà tôi từng dùng
      Vừa khởi động là quạt đã quay, và khi cắm thiết bị Thunderbolt thì cũng hay bị kernel panic
      M1 Max MBP mà tôi đang dùng bây giờ thì ổn định hoàn hảo
  • Dự án trông khá ổn
    Nhưng việc phát triển trên macOS ngày càng khó hơn, và ngay cả khi phát hiện được throttling thì tôi vẫn nghi ngờ là thực tế có thể làm gì với nó
    Không chỉnh được tốc độ quạt, mà undervolt cũng không thể phải không?

    • Trường hợp của tôi thì dùng iStat Menus để tự chỉnh đường cong quạt
      Đường cong mặc định quá chậm nên throttling xảy ra trước
      Trên Apple Silicon, dùng High Power Mode thì quạt sẽ quay nhanh hơn
      Giờ tôi không còn dùng đường cong tùy chỉnh nữa, nhưng trên 14" M4 Max thì khá ồn
      MacBook Air thì không có quạt, nên chỉ còn cách để máy tự tản nhiệt
    • Tôi dùng Macs Fan Control để chỉnh RPM quạt theo nhiệt độ CPU
      Với thiết lập mặc định thì máy lên hơn 90 độ, nên tôi đã chỉnh bảo thủ hơn
      Liên kết GitHub
    • Tôi thật sự cần một ứng dụng như thế này, và giờ thì cuối cùng đã có
      Thỉnh thoảng có tiến trình chạy quá đà làm máy bị throttling, đến lúc nhận ra thì pin đã tụt mất một nửa
    • Cuối cùng thì thứ bạn có thể làm chỉ là đóng ứng dụng hoặc nghỉ một lúc
      Vấn đề này xảy ra khá thường xuyên khi có nhiều ứng dụng chạy nền
  • Nếu đưa lên Homebrew thì có thể nhận ký mã và công chứng miễn phí
    Nếu được phân phối theo cách đó thì sẽ rất tuyệt

    • Thông tin hay đấy. Không biết có cách ký miễn phí cho Windows không nhỉ
    • Ồ, tôi không biết điều đó. Tôi cứ tưởng còn tùy vào cấu hình phía nhà phát triển, chắc phải tìm hiểu mới được
  • Giả thuyết của tôi là vấn đề không nằm ở CPU mà là bộ điều khiển USB đang làm bão hòa nhiệt
    Có vẻ không phải CPU/GPU mà là cả thân máy bị quá nhiệt, làm cản trở việc tản nhiệt rồi cuối cùng dẫn tới throttling
    Cần thử nghiệm thêm với adapter hoặc màn hình khác

    • Tôi cũng dùng i9 2019, và khi đổi cổng sạc thì throttling biến mất
      Có lẽ bạn nói đúng
    • Tôi chưa hiểu hoàn toàn, nhưng M2 Air của tôi cũng có triệu chứng tương tự
      Khi cắm vào màn hình 4K 144Hz rồi mở Zoom hoặc nhiều luồng video thì máy nóng lên rất nhiều
      Có lẽ không hẳn do bộ điều khiển USB mà chỉ đơn giản là tải quá cao
    • Hiện tượng này được gọi là thermal soaking
  • Có vẻ trang web đã sập vì lưu lượng tăng đột biến
    Kho mã nguồn là angristan/MacThrottle

    • Đã sửa xong. Cloudflare Workers đang được cấu hình ở chế độ fail closed nên chặn mất lưu lượng
  • Trong iStat Menus, nếu CPU 100% nhưng mức tiêu thụ điện thấp thì có thể nghĩ là throttling,
    nhưng hiện tượng tương tự cũng xảy ra khi cắm vào bộ sạc USB-C công suất thấp
    Sẽ hay hơn nếu thêm tính năng phát hiện công suất sạc

    • Tôi cũng từng gặp đúng vấn đề này khi chơi D&D bằng M1 MacBook Air
      Khi vừa sạc vừa dùng thì máy nóng lên nên throttling rất nặng, nhưng sạc trước buổi chơi thì hết hẳn
    • Trước đây tôi từng bị công suất của bộ đổi nguồn không đủ, đến mức đang chơi game thì pin cạn và máy tắt
      Từ đó tôi hiểu vì sao các thế hệ sau lại có bộ đổi nguồn công suất lớn hơn
    • Nếu vậy thì tôi thắc mắc tại sao không thể chỉ dựa vào nhiệt độ lõi để xác định throttling
      Chẳng phải nhiệt độ mới là biến điều khiển trực tiếp sao?
    • iStat Menus có hiển thị công suất bộ sạc, nhưng vì sao hiện tượng này xảy ra thì tôi vẫn thấy khó hiểu
  • Nếu hiển thị mức dùng CPU và điện năng hệ thống trên thanh menu thì có thể nhận ra bất thường ngay
    exelban/stats

    • Tôi cũng đã nghi ngờ throttling lần đầu theo cách đó
      Thấy CPU usage cao mà điện năng lại giảm là tôi nhận ra ngay
  • Hy vọng MacBook Air M5 tiếp theo sẽ có làm mát bằng vapor chamber
    Hiện giờ có vẻ Apple đang ưu tiên giảm tiếng ồn hơn là khả năng tản nhiệt
    Vì vậy tôi buộc tốc độ quạt tối thiểu cao hơn

    • Vapor Chamber tốt cho việc phân tán nhiệt tức thời, nhưng cuối cùng nhiệt vẫn sẽ được truyền sang thân nhôm
      Khi phần thân đạt cân bằng nhiệt với môi trường thì khả năng tỏa nhiệt cũng chạm giới hạn
      Nếu có quạt thì chỉ với tấm đồng và luồng gió cũng đã đủ giải quyết
      Cuối cùng đây vẫn là vấn đề của định luật bảo toàn năng lượng
  • Có vẻ có lỗi thông báo thermal pressure
    Không biết trong ứng dụng bạn có gặp vấn đề như vậy không
    Vấn đề liên quan

    • Tôi cũng từng thấy trạng thái không được cập nhật khi dùng ProcessInfo.processInfo.thermalState
      Nhưng với cách nhận thông báo qua thermald mà tôi đang dùng hiện tại thì không có vấn đề đó
  • Tôi thắc mắc vì sao lại dùng @_silgen_name để khai báo trực tiếp Darwin API
    import Darwin không truy cập được sao?

    • Có vẻ thực sự là chỉ import Darwin thì API đó không được expose