Những người góp phần vào độ trễ âm thanh

Trang này tập trung vào những yếu tố góp phần tạo ra độ trễ đầu ra, nhưng một cuộc thảo luận tương tự cũng áp dụng cho độ trễ đầu vào.

Giả sử mạch analog không đóng góp đáng kể thì các yếu tố chính ở cấp độ bề mặt đóng góp vào độ trễ âm thanh như sau:

  • Ứng dụng
  • Tổng số bộ đệm trong đường ống
  • Kích thước của mỗi bộ đệm, tính bằng khung
  • Độ trễ bổ sung sau bộ xử lý ứng dụng, chẳng hạn như từ DSP

Mặc dù danh sách những người đóng góp ở trên có thể chính xác nhưng nó cũng có thể gây hiểu nhầm. Lý do là số lượng bộ đệm và kích thước bộ đệm có nhiều tác dụng hơn là nguyên nhân . Điều thường xảy ra là sơ đồ bộ đệm nhất định được triển khai và thử nghiệm, nhưng trong quá trình thử nghiệm, âm thanh bị chạy quá mức hoặc bị chạy quá mức được nghe dưới dạng "tiếng nhấp chuột" hoặc "bật". Để bù lại, người thiết kế hệ thống sau đó tăng kích thước bộ đệm hoặc số lượng bộ đệm. Điều này mang lại kết quả mong muốn là loại bỏ tình trạng chạy thiếu hoặc vượt mức, nhưng nó cũng có tác dụng phụ không mong muốn là tăng độ trễ. Để biết thêm thông tin về kích thước bộ đệm, hãy xem video Độ trễ âm thanh: kích thước bộ đệm .

Một cách tiếp cận tốt hơn là tìm hiểu nguyên nhân của việc chạy thiếu và vượt mức, sau đó khắc phục chúng. Điều này giúp loại bỏ các tạp âm và có thể cho phép bộ đệm nhỏ hơn hoặc ít hơn và do đó giảm độ trễ.

Theo kinh nghiệm của chúng tôi, những nguyên nhân phổ biến nhất dẫn đến việc thiếu và vượt mức bao gồm:

  • Linux CFS (Bộ lập lịch hoàn toàn công bằng)
  • các luồng có mức độ ưu tiên cao với lập lịch SCHED_FIFO
  • đảo ngược ưu tiên
  • độ trễ lập kế hoạch dài
  • xử lý ngắt chạy dài
  • thời gian vô hiệu hóa ngắt dài
  • quản lý năng lượng
  • hạt nhân bảo mật

Lập lịch CFS và SCHED_FIFO của Linux

Linux CFS được thiết kế để phù hợp với các khối lượng công việc cạnh tranh chia sẻ tài nguyên CPU chung. Sự công bằng này được thể hiện bằng tham số Nice trên mỗi luồng. Giá trị Nice nằm trong khoảng từ -19 (kém đẹp nhất hoặc được phân bổ thời gian CPU nhiều nhất) đến 20 (đẹp nhất hoặc phân bổ thời gian CPU ít nhất). Nói chung, tất cả các luồng có giá trị Nice nhất định sẽ nhận được thời gian CPU gần như bằng nhau và các luồng có giá trị Nice thấp hơn về số lượng sẽ nhận được nhiều thời gian CPU hơn. Tuy nhiên, CFS chỉ “công bằng” trong thời gian quan sát tương đối dài. Trong thời gian quan sát ngắn hạn, CFS có thể phân bổ tài nguyên CPU theo những cách không mong muốn. Ví dụ: nó có thể đưa CPU ra khỏi một luồng có độ phân giải thấp về mặt số lượng để chuyển sang một luồng có độ phân giải cao về mặt số lượng. Trong trường hợp âm thanh, điều này có thể dẫn đến chạy thiếu hoặc tràn.

Giải pháp rõ ràng là tránh CFS cho các luồng âm thanh hiệu suất cao. Bắt đầu với Android 4.1, các luồng như vậy hiện sử dụng chính sách lập lịch SCHED_FIFO thay vì chính sách lập lịch SCHED_NORMAL (còn gọi là SCHED_OTHER ) do CFS triển khai.

Ưu tiên SCHED_FIFO

Mặc dù các luồng âm thanh hiệu suất cao hiện sử dụng SCHED_FIFO nhưng chúng vẫn dễ bị ảnh hưởng bởi các luồng SCHED_FIFO có mức độ ưu tiên cao hơn. Đây thường là các luồng công việc hạt nhân, nhưng cũng có thể có một số luồng của người dùng không phải âm thanh có chính sách SCHED_FIFO . Mức độ ưu tiên SCHED_FIFO khả dụng nằm trong khoảng từ 1 đến 99. Các luồng âm thanh chạy ở mức ưu tiên 2 hoặc 3. Điều này để lại mức ưu tiên 1 khả dụng cho các luồng có mức độ ưu tiên thấp hơn và mức độ ưu tiên 4 đến 99 cho các luồng có mức độ ưu tiên cao hơn. Chúng tôi khuyên bạn nên sử dụng mức độ ưu tiên 1 bất cứ khi nào có thể và dành mức độ ưu tiên từ 4 đến 99 cho những chuỗi được đảm bảo hoàn thành trong một khoảng thời gian giới hạn, thực thi với khoảng thời gian ngắn hơn khoảng thời gian của chuỗi âm thanh và được biết là không ảnh hưởng đến việc lên lịch của các chủ đề âm thanh.

Lập kế hoạch tỷ lệ đơn điệu

Để biết thêm thông tin về lý thuyết phân công các mức độ ưu tiên cố định, hãy xem bài viết Wikipedia Lập lịch trình đơn điệu tốc độ (RMS). Điểm mấu chốt là các ưu tiên cố định phải được phân bổ nghiêm ngặt dựa trên thời gian, với các ưu tiên cao hơn được giao cho các chủ đề có thời gian ngắn hơn, chứ không dựa trên "tầm quan trọng" được nhận thức. Các luồng không định kỳ có thể được mô hình hóa thành các luồng định kỳ, sử dụng tần suất thực thi tối đa và tính toán tối đa cho mỗi lần thực thi. Nếu một luồng không định kỳ không thể được mô hình hóa như một luồng định kỳ (ví dụ: nó có thể thực thi với tần số không giới hạn hoặc tính toán không giới hạn trên mỗi lần thực hiện), thì nó không nên được chỉ định mức ưu tiên cố định vì điều đó sẽ không tương thích với việc lập lịch trình của các luồng định kỳ thực sự .

Đảo ngược ưu tiên

Đảo ngược mức độ ưu tiên là một chế độ lỗi cổ điển của các hệ thống thời gian thực, trong đó tác vụ có mức độ ưu tiên cao hơn bị chặn trong thời gian không giới hạn để chờ tác vụ có mức độ ưu tiên thấp hơn giải phóng tài nguyên, chẳng hạn như (trạng thái chia sẻ được bảo vệ bởi) một mutex . Xem bài viết " Tránh đảo ngược mức độ ưu tiên " để biết các kỹ thuật giảm thiểu nó.

Lập kế hoạch độ trễ

Độ trễ lập lịch là khoảng thời gian từ khi một luồng sẵn sàng chạy cho đến khi quá trình chuyển đổi ngữ cảnh kết quả hoàn tất để luồng thực sự chạy trên CPU. Độ trễ càng ngắn thì càng tốt và bất cứ điều gì trên hai mili giây đều gây ra sự cố cho âm thanh. Độ trễ lập lịch dài rất có thể xảy ra trong quá trình chuyển đổi chế độ, chẳng hạn như khởi động hoặc tắt CPU, chuyển đổi giữa nhân bảo mật và nhân thông thường, chuyển từ chế độ nguồn điện đầy đủ sang chế độ nguồn điện thấp hoặc điều chỉnh tần số và điện áp xung nhịp CPU .

Ngắt

Trong nhiều thiết kế, CPU 0 phục vụ tất cả các ngắt bên ngoài. Vì vậy, trình xử lý ngắt chạy trong thời gian dài có thể trì hoãn các ngắt khác, đặc biệt là các ngắt hoàn thành truy cập bộ nhớ trực tiếp âm thanh (DMA). Thiết kế các trình xử lý ngắt để hoàn thành nhanh chóng và trì hoãn công việc kéo dài cho một luồng (tốt nhất là luồng CFS hoặc luồng SCHED_FIFO có mức độ ưu tiên 1).

Tương tự, việc vô hiệu hóa các ngắt trên CPU 0 trong một thời gian dài có cùng kết quả là làm trì hoãn việc cung cấp các ngắt âm thanh. Thời gian vô hiệu hóa ngắt dài thường xảy ra trong khi chờ khóa quay hạt nhân. Xem lại các khóa xoay này để đảm bảo chúng được giới hạn.

Quản lý năng lượng, hiệu suất và nhiệt

Quản lý năng lượng là một thuật ngữ rộng bao gồm các nỗ lực giám sát và giảm mức tiêu thụ năng lượng trong khi tối ưu hóa hiệu suất. Quản lý nhiệtlàm mát máy tính tương tự nhau nhưng tìm cách đo lường và kiểm soát nhiệt để tránh hư hỏng do nhiệt dư thừa. Trong nhân Linux, bộ điều chỉnh CPU chịu trách nhiệm về chính sách cấp thấp, trong khi chế độ người dùng định cấu hình chính sách cấp cao. Các kỹ thuật được sử dụng bao gồm:

  • chia tỷ lệ điện áp động
  • chia tần số động
  • cho phép lõi động
  • chuyển mạch cụm
  • cổng điện
  • cắm nóng (hotswap)
  • nhiều chế độ ngủ khác nhau (dừng, dừng, chạy không tải, tạm dừng, v.v.)
  • quá trình di chuyển
  • mối quan hệ của bộ xử lý

Một số hoạt động quản lý có thể dẫn đến "sự ngừng hoạt động" hoặc thời gian mà bộ xử lý ứng dụng không thực hiện công việc hữu ích nào. Những lần dừng công việc này có thể gây nhiễu âm thanh, vì vậy việc quản lý như vậy phải được thiết kế cho trường hợp ngừng công việc xấu nhất có thể chấp nhận được khi âm thanh đang hoạt động. Tất nhiên, khi hiện tượng thoát nhiệt sắp xảy ra, việc tránh hư hỏng vĩnh viễn còn quan trọng hơn âm thanh!

Hạt nhân bảo mật

Nhân bảo mật dành cho Quản lý quyền kỹ thuật số (DRM) có thể chạy trên cùng (các) lõi bộ xử lý ứng dụng giống như lõi được sử dụng cho nhân hệ điều hành chính và mã ứng dụng. Bất cứ lúc nào trong đó một hoạt động của nhân bảo mật đang hoạt động trên một lõi thực sự sẽ là sự ngừng hoạt động thông thường thường chạy trên lõi đó. Đặc biệt, điều này có thể bao gồm công việc âm thanh. Về bản chất, hành vi bên trong của nhân bảo mật là không thể dò được từ các lớp cấp cao hơn và do đó, bất kỳ sự bất thường nào về hiệu năng do nhân bảo mật gây ra đều đặc biệt nguy hiểm. Ví dụ: các hoạt động của nhân bảo mật thường không xuất hiện trong dấu vết chuyển đổi ngữ cảnh. Chúng ta gọi đây là "thời gian đen tối" - thời gian đã trôi qua nhưng không thể quan sát được. Hạt nhân bảo mật phải được thiết kế để dừng hoạt động trong trường hợp xấu nhất có thể chấp nhận được khi âm thanh đang hoạt động.