Vulkan: Bộ đệm thống nhất so với hằng số đẩy cho dữ liệu tĩnh


8

Tôi đang đấu tranh để hiểu sự khác biệt về khái niệm giữa bộ đệm đồng nhất và hằng số đẩy. Từ những gì tôi có thể thu thập bằng cách đọc thông số kỹ thuật, sự khác biệt chính là:

  1. Buffers Uniform có thể nhiều lớn hơn hằng đẩy.
  2. UBO sử dụng std140, PC sử dụng std430.
  3. Các UBO có thể được cập nhật bất cứ lúc nào với vkCmdUpdateBuffer (hoặc ánh xạ máy chủ) và duy trì giá trị của chúng nếu không, PC phải được đẩy lại cho mỗi lần kết xuất. (Điều này làm tôi ngạc nhiên - dựa trên tên. Tôi nghĩ rằng tôi thực sự sẽ cập nhật các hằng số trong đường ống tại chỗ, và những thay đổi đó vẫn tồn tại)

Trong kịch bản của tôi, tôi có khoảng ~ 200 byte dữ liệu mà tôi mong đợi hầu như không đổi . Đó là, tôi sẽ thay đổi chúng rất ít khi. Sẽ tốt hơn nếu (giả sử kích thước cho phép) sử dụng hằng số đẩy mặc dù tôi phải gửi lại chúng trong mỗi bộ đệm lệnh? Hoặc sẽ tốt hơn nếu sử dụng UBO 200 byte và chỉ cập nhật nó không thường xuyên với vkCmdUpdatebuffer?

Cũng thế. Điều gì xảy ra nếu tôi có, ví dụ như float random_seedtôi sẽ cập nhật mỗi khi shader chạy? Giả sử tôi đã có UBO, sẽ tốt hơn nếu kết hợp với UBO, mặc dù phần còn lại của UBO là không đổi, hoặc tôi sẽ có được lợi ích từ việc sử dụng hằng số đẩy cho biến này, vì vậy tôi có thể tránh phải vkCmdUpdateBuffer trước mỗi lần kết xuất?


Chào mừng bạn đến với trang web Trao đổi đồ họa máy tính! Tôi không quen thuộc với Vulkan nhưng có vẻ như sử dụng UBO sẽ hiệu quả hơn trong trường hợp của bạn (bạn có thể thử so sánh hiệu suất của cả hai phương pháp trong một chương trình mẫu). Những API đồ họa nào bạn quen thuộc? Ngoài ra, bạn có thể quan tâm đến bài thuyết trình GDC 2012 này: Đừng vứt bỏ tất cả: Quản lý bộ đệm hiệu quả
xóa

Từ tài liệu Vulkan : trong khi UBO phân bổ một khối bộ nhớ video trên GPU (mà bạn có thể cập nhật vào thời gian sau), Push Constant không sử dụng bộ nhớ video (đó là lý do tại sao nó phải được cung cấp trong mỗi cuộc gọi rút / tính toán, nếu không thì shader sẽ không biết nên sử dụng giá trị nào). Tôi đoán nó được lưu trữ trong một khu vực lưu trữ nhanh, ngắn hạn khác trên GPU, mặc dù các chi tiết có thể phụ thuộc vào nhà cung cấp GPU của bạn.
lau

Câu trả lời:


8

UBO có thể được cập nhật bất cứ lúc nào với vkCmdUpdateBuffer

Từ thông số kỹ thuật: "vkCmdUpdateBuffer chỉ được phép bên ngoài một lượt kết xuất." Vì vậy, "bất cứ lúc nào" không phải là trường hợp.

Ngay cả khi nó được cho phép bên trong pass render, nó vẫn là một hoạt động chuyển. Có nghĩa là bạn cần đồng bộ hóa việc chuyển bộ nhớ với các lệnh sử dụng nó. Mà làm chậm hiệu suất.

Đối với điều chung Không đổi so với điều thống nhất, hãy sử dụng phán đoán của bạn. Bằng cách "phán xét", ý tôi là chỉ cần nhìn vào cách họ làm việc. Các hằng số đẩy cho phép bạn thay đổi dữ liệu của họ bất cứ lúc nào mà không cần thực hiện các quy trình nặng như hoạt động bộ nhớ, đồng bộ hóa hoặc thay đổi trạng thái mô tả. Rõ ràng, chúng là để thường xuyên thay đổi dữ liệu. Làm thế nào thường xuyên là "thường xuyên"? Vâng, đó là một cuộc gọi phán xét.

Không, hồ sơ sự khác biệt hiệu suất.


2

Tôi có khoảng ~ 200 byte dữ liệu mà tôi mong đợi hầu hết là không đổi. Đó là, tôi sẽ thay đổi chúng rất ít khi.

Nếu dữ liệu thay đổi không thường xuyên, bạn có thể sử dụng Hằng số chuyên môn hóa . Chúng được đặt khi đường ống được tạo và đường ống mới phải được tạo nếu bạn cần thay đổi các giá trị. Đối với một sự kiện không thường xuyên, như thay đổi kích thước cửa sổ, đây có thể là một chi phí chấp nhận được.

Điều gì xảy ra nếu tôi có ví dụ: float Random_seed mà tôi sẽ cập nhật mỗi khi shader chạy?

Đó là một trường hợp sử dụng hoàn hảo cho các hằng số đẩy. Bạn có thể giữ tất cả các dữ liệu khác trong UBO (hoặc trong Hằng số chuyên môn hóa) và thay đổi giá trị này bằng VkCmdPushConstants.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.