Nổi, gấp đôi hoặc cả hai cho lớp Vector 2D?


11

Tôi hiện đang viết một công cụ trò chơi 2D dựa trên nền tảng OpenGL nhỏ cho studio của chúng tôi. Khi tôi nghiên cứu sử dụng lớp 2D Vector nào, tôi tình cờ thấy ba mô hình thiết kế khác nhau:

  • Float & Call-by-value, như trong bài viết này của Gamasutra . Có vẻ là nhanh nhưng cung cấp độ chính xác nhỏ (xem thêm Chủ đề này ). Pro: Nhanh chóng, di động và tương thích với hầu hết các thư viện.

  • Double & Call-by-Reference. Nếu tôi hiểu đúng bài viết trên, tôi cũng có thể sử dụng 2 biến chính xác kép thay vì 4 số float. Theo chủ đề trên đôi vẫn chậm hơn so với float.

  • Mẫu cho double và float: Cuốn sách phổ biến rộng rãi " Game Engine Architecture " sử dụng các mẫu để làm cho nó có thể sử dụng float và double khi cần. Nhược điểm rõ ràng là phình mã. Ngoài ra, tôi nghi ngờ rằng mã có thể được tối ưu hóa mà không cần viết hai lớp về cơ bản.

Tôi sẽ đánh giá cao để tìm hiểu những giải pháp bạn đang sử dụng trong các công cụ nội bộ của mình và mức độ chính xác của các công cụ trò chơi phổ biến, vì vậy tôi có thể quyết định giải pháp nào tôi sẽ thực hiện trong công cụ của mình. Hiện tại tôi đang nghĩ về việc sử dụng độ chính xác của float và sống với nó.


Chậm hơn ở đâu ? Bạn không thể nói về tốc độ nếu điều đó không gắn liền với một kiến ​​trúc cụ thể.
o0 '.

2
@ Lo'oris: Tôi không biết bất kỳ kiến ​​trúc nào trong đó gấp đôi nhanh hơn nổi.

Thay vì viết lớp vectơ của riêng bạn, hãy xem xét sử dụng Sony ( Bulletphysics.org/BONS/phpBB3/ mẹo ). Đây là một "thư viện" chỉ dành cho tiêu đề thả xuống dễ dàng đã được tối ưu hóa vi mô và tất cả các thư viện vectơ về cơ bản đều có cùng một giao diện bên ngoài.

@Joe: 2 nhân đôi thay vì 4 phao?
o0 '.

@ Lo'oris: Câu hỏi được diễn đạt hơi kỳ lạ, tôi không biết người hỏi có nhầm lẫn hay không - bạn sử dụng hai nhân đôi "thay vì" bốn phao khi giao dịch với SIMD, vì thanh ghi rộng 128 bit. Bạn vẫn cần xử lý một số lượng bằng nhau và bạn đang thực hiện ở tốc độ một nửa.

Câu trả lời:


9

Tôi luôn sử dụng float trừ khi tôi có lý do để sử dụng gấp đôi, nhiều như tôi sử dụng int trừ khi tôi có lý do để sử dụng int64_t.

Phao không có vấn đề gì khi thực hiện số học số nguyên chính xác đến 2 24 , đó là điều mà hầu hết mọi người (hầu hết là phi lý) sợ. Nhân đôi không giải quyết được vấn đề của các giá trị phổ biến là không thể biểu thị chính xác - cho dù bạn nhận được 0.10000001 hay 0.10000000000000001, bạn vẫn phải đảm bảo mã của mình coi nó "bằng" với 0,09999999.

Việc nhân đôi chậm hơn trên mọi nền tảng mà bạn sẽ quan tâm khi viết trò chơi, chiếm gấp đôi băng thông bộ nhớ và có ít hướng dẫn CPU chuyên dụng hơn.

Phao đơn chính xác vẫn là tiêu chuẩn cho giao diện đồ họa phần cứng, cả ở phía C / C ++ và bên trong shader.

Có thể bạn sẽ cần một vectơ kép tại một số điểm, nhưng nó nên được sử dụng khi cần chứ không phải theo mặc định.

Đối với việc tạo khuôn mẫu - bạn nói đúng, để đạt hiệu suất tối đa, bạn sẽ muốn chuyên môn hóa các mẫu theo cách thủ công. Ngoài ra, tôi đã chạy một số thử nghiệm cho một số mã templated vào cuối tuần qua (tạo một IntRect và FloatRect 4 ple), và thấy rằng phiên bản templated mất khoảng 20 lần để biên dịch hơn là chỉ lặp lại mã, khoảng 15 dòng . Sự lặp lại tệ, nhưng chờ đợi các trình biên dịch sẽ hút nhiều hơn - và không phải là tôi sẽ cần StringRect hay FooRect.


"Nhân đôi chậm hơn trên mọi nền tảng [V]] - Cần trích dẫn.
đỉnh

3

Khung trò chơi Microsoft XNA có lớp Vector2 sử dụng phao. Đây sẽ là lý do lớn nhất của cá nhân tôi khi đi phao, vì tôi tin tưởng sự khôn ngoan và kinh nghiệm của đội XNA sẽ lớn hơn nhiều so với chính tôi.

Tôi thấy khá thú vị khi đọc câu trả lời trong câu hỏi Stack Overflow này: "Float vs Double Performance" . Ngoài ra còn có một chủ đề gamedev.net với một số thảo luận về hiệu suất gấp đôi trong GPU. Tôi nghĩ thật an toàn khi cho rằng nhân đôi chậm hơn phao, ít nhất là trong nhiều GPU và cá nhân tôi luôn sử dụng các chức năng OpenGL nổi so với các đối tác kép của chúng. Điều này có thể không áp dụng hiện nay, nhưng nếu bạn cho rằng không phải ai chạy trò chơi của bạn cũng có GPU mới nhất với hỗ trợ nhân đôi, tôi nghĩ đây là lý do đủ để sử dụng phao và đạt được hiệu năng cao hơn.


1
Từ câu hỏi SO: "Trên các bộ xử lý x86, ít nhất, float và double sẽ được chuyển đổi thành một thực tế 10 byte bởi FPU để xử lý." Mặc dù điều này là đúng, nhưng nó bỏ qua cả hai hướng dẫn SIMD và các yêu cầu bộ nhớ bổ sung (= kém hơn bộ nhớ cache, băng thông bộ nhớ nhiều hơn), cả hai đều tiếp tục làm cho nó chậm hơn so với trôi nổi trong các thử nghiệm trong thế giới thực.

Tôi hình dung có một cái bẫy. Bạn nên nhận xét rằng vào câu trả lời SO, tôi sẽ đưa ra.
Ricket

Nó đã ở đó như là một bình luận.

1
Vì bạn đã đưa lên XNA, tôi cũng có thể chỉ ra rằng Direct2D cũng sử dụng các số float chính xác đơn.
Mike Strobel

Và để hoàn thiện, OpenGL có các phiên bản nổi và gấp đôi các phương thức của nó, vì vậy nó trung lập theo nghĩa này.
Ricket
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.