Tại sao việc truy cập vào một float nổi làm cho shader của tôi chậm hơn hai lần?


7

Shader mảnh của tôi đã bị chậm lại đáng kể bởi một thay đổi gần đây và tôi đã cố gắng để hiểu tại sao.

Tôi đã tách phần chậm chính để truy cập vào một số float cụ thể. Nếu tôi bao gồm dòng này:

float not_used = my_uniform;

sau đó shader chạy chậm hơn hai lần so với khi không có dòng này. Các not_usedphao không bao giờ được tham chiếu một lần nữa.

Tại sao điều này sẽ xảy ra? Tôi hy vọng hiểu nó để tôi có thể cố gắng đưa ra một cách giải quyết nhanh hơn.

Tôi đang chạy ứng dụng này trên máy Mac với Intel HD Graphics 3000. Tôi đang đo hiệu suất bằng cách thực hiện các truy vấn dấu thời gian OpenGL trước và sau khi thực hiện glDrawcác cuộc gọi của mình và xem xét các khoảng thời gian ms. Tôi có thể cung cấp thêm thông số kỹ thuật / chi tiết nếu nó hữu ích trong chẩn đoán vấn đề.


Bạn đang đo hiệu suất sai. Các cuộc gọi vẽ có thể được đệm, do đó bạn phải gọi glFinish()hoặc các chức năng hoán đổi bộ đệm của mình, để mã thực sự được thực thi. Ngoài ra, một trình biên dịch glsl tốt sẽ loại bỏ mọi đồng phục không sử dụng khỏi mã của bạn.
akaltar

@akaltar, tôi đang đo hiệu suất ở phía GPU bằng cách sử dụng gl{Begin,End}Queryvới GL_TIME_ELAPSEDsố liệu. Thiết lập này được thiết kế để tính đến cách các lệnh OpenGL được thực thi không đồng bộ với CPU. Xem opengl.org/registry/specs/ARB/timer_query.txt
Tyler

2
Bạn có thể hiển thị toàn bộ shader?
Roy T.

về cơ bản là không thể ở dạng hiện tại của nó. mọi trình biên dịch trên hành tinh đều tối ưu hóa các biến không sử dụng. hoặc có thể không nếu bạn sử dụng Mesa với một số loại cờ gỡ lỗi và trong triển khai phần mềm. nhưng bạn đang ở trên Mac nên trình biên dịch glsl là một số phiên bản llvm được nhúng trong trình điều khiển. Hoặc, trình tạo bóng của bạn không làm gì trước đó và hiện tại nó có quyền truy cập vào đồng phục được tối ưu hóa. Vì vậy, sự khác biệt là một tiếng ồn đo. bạn chỉ có thể kiểm tra sự khác biệt FPS khi đo độ hoàn hảo của GPU.
v.oddou

2
@Tyler Hai lần chậm như thế nào? 16/32 ms hay 0,001 / 0,002ms? Ngoài ra, giá trị đồng nhất có phải là số tròn đẹp không (0,1,2, -1, v.v.)? Có khả năng GPU cố gắng biên dịch lại shader nếu đồng phục có giá trị tối ưu hóa thuận tiện (ví dụ: có 0 trong tính toán sẽ vô hiệu hóa hoàn toàn một số trong số chúng và có 1 sẽ loại bỏ các lần đọc và nhân đồng nhất).
rắn5

Câu trả lời:


2

Bạn đang sử dụng glGetUniformLocationđể có được vị trí của đồng phục? Nếu đồng phục đã được tối ưu hóa, chức năng này sẽ trả về -1, sau đó khi bạn đưa -1 làm đối số vị trí cho glUniform1f, sẽ không có gì được gửi đến trình đổ bóng và điều này có thể sẽ tiết kiệm thời gian.


-2

Âm thanh như một vấn đề liên kết hoặc kích thước bộ nhớ. Có lẽ với sự gia tăng này, nhu cầu bộ nhớ của bạn bị tăng lên do một số phép thuật làm chậm MAC (tôi không sử dụng MAC cho mình) nhưng rất có thể nó đang gây ra vấn đề căn chỉnh.

Hãy xem xét một cấu trúc kiểu C ++ trong mã giả:

struct myStruct {
    char x;
    int y;
}

Nếu cấu trúc này được phép tạo bình thường với kích thước int là 4 byte và kích thước char là 1 byte, cấu trúc sẽ là 8 byte, không phải là 5 byte dự kiến. Điều này là do nếu một từ (4 byte trong hệ thống 32 bit) không được căn chỉnh trên ranh giới 4 byte thì CPU sẽ phải thực hiện nhiều công việc hơn để di chuyển từ này. Đây là một hướng dẫn lắp ráp duy nhất để di chuyển một từ (int trong trường hợp này) nếu nó được căn chỉnh chính xác. Nếu nó không được căn chỉnh chính xác thì một nửa từ được di chuyển, một con trỏ được thay đổi và nửa còn lại và điều này làm mọi thứ chậm lại. Vì vậy, một cấu trúc thường sẽ cố gắng căn chỉnh chính nó khi được biên dịch.

Nếu bạn đã làm một cái gì đó như #pragma được đóng gói sẽ loại bỏ các byte đệm không sử dụng, kích thước sẽ là 5 byte dự kiến ​​và mọi thứ sẽ chậm hơn.

Vì vậy, tôi nghĩ rằng bạn cần nhìn vào nơi bạn đang khai báo float đó và những gì được khai báo ngay trước nó và sau nó để tìm ra vấn đề căn chỉnh bộ nhớ có thể đến từ đâu.


3
không tồn tại các vấn đề liên kết như vậy trên GPU. chúng là các DSP RISC cơ bản và không cho phép đọc sai. Hơn nữa, các biến thống nhất được lưu trữ trong các bộ đệm không đổi, phù hợp với các thanh ghi trong khi thực hiện luồng.
v.oddou
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.