Tại sao Farseer 2.x lưu trữ tạm thời là thành viên mà không phải trên ngăn xếp? (.MẠNG LƯỚI)


10

CẬP NHẬT: Câu hỏi này đề cập đến Farseer 2.x. 3.x mới hơn dường như không làm điều này.

Hiện tại tôi đang sử dụng Công cụ Vật lý Farseer khá rộng rãi và tôi nhận thấy rằng nó dường như lưu trữ rất nhiều loại giá trị tạm thời như là thành viên của lớp, chứ không phải trên ngăn xếp như mọi người mong đợi.

Đây là một ví dụ từ Bodylớp:

private Vector2 _worldPositionTemp = Vector2.Zero;

private Matrix _bodyMatrixTemp = Matrix.Identity;
private Matrix _rotationMatrixTemp = Matrix.Identity;
private Matrix _translationMatrixTemp = Matrix.Identity;

public void GetBodyMatrix(out Matrix bodyMatrix)
{
    Matrix.CreateTranslation(position.X, position.Y, 0, out _translationMatrixTemp);
    Matrix.CreateRotationZ(rotation, out _rotationMatrixTemp);
    Matrix.Multiply(ref _rotationMatrixTemp, ref _translationMatrixTemp, out bodyMatrix);
}

public Vector2 GetWorldPosition(Vector2 localPosition)
{
    GetBodyMatrix(out _bodyMatrixTemp);
    Vector2.Transform(ref localPosition, ref _bodyMatrixTemp, out _worldPositionTemp);
    return _worldPositionTemp;
}

Có vẻ như nó là một tối ưu hóa hiệu suất bằng tay. Nhưng tôi không thấy làm thế nào điều này có thể giúp hiệu suất? (Nếu bất cứ điều gì tôi nghĩ rằng nó sẽ làm tổn thương bằng cách làm cho các đối tượng lớn hơn nhiều).

Câu trả lời:


6

Mặc dù trong các loại giá trị .NET được lưu trữ trên ngăn xếp, dẫn đến chi phí phân bổ tối thiểu, tuy nhiên nó không loại bỏ chi phí khởi tạo.

Trong trường hợp này, chúng ta có một tập hợp các hàm sử dụng một hoặc hai ma trận tạm thời, điều này sẽ dẫn đến việc khởi tạo 16-32 float mỗi cuộc gọi. Mặc dù điều này có vẻ không đáng kể, nhưng nếu các phương thức được sử dụng thường xuyên đủ (giả sử, hàng nghìn và hàng nghìn lần trên mỗi khung hình), tổng chi phí có thể có tác động có ý nghĩa. Nếu một kỹ thuật như vậy được sử dụng một cách có hệ thống trên tất cả các phương pháp như vậy, thì việc loại bỏ chi phí có thể là đáng kể.

Mặc dù việc sử dụng một kỹ thuật như vậy sẽ loại bỏ khả năng cung cấp sự an toàn của luồng ở mức độ trên mỗi đối tượng, nhưng nói chung là không khôn ngoan khi cung cấp sự đảm bảo đó ở mức độ chi tiết như vậy.


Bạn có chắc chắn về điều đó không? Một suy nghĩ của tôi là nó có thể tránh việc gọi các nhà xây dựng. Nhưng đối với các loại giá trị, bạn không cần gọi hàm tạo - bao gồm hàm tạo không tham số mặc định - nếu bạn sẽ đặt tất cả các thành viên (hoặc chuyển nó làm outtham số). Tôi khá chắc chắn rằng toàn bộ điểm của quy tắc này là để trình biên dịch có thể bỏ qua việc xóa bộ nhớ đó - đúng không? (Có thực sự chậm khi di chuyển con trỏ ngăn xếp không?)
Andrew Russell

Đáng ngạc nhiên, không? Thật không may, nếu bạn kiểm tra IL được tạo, các ma trận tạm thời được khởi tạo. Một vài thử nghiệm nhanh cho thấy phiên bản temp thành viên nhanh hơn ~ 10-15%.
Jason Kozak

1
Tôi sững sờ . Trong "Tìm hiểu về hiệu suất khung XNA" (GDC2008) Shawn Hargreaves nói về các cấu trúc: "[JIT] thường sẽ tìm ra: 'trong dòng tiếp theo, anh ta lập tức đặt cả ba trường [của Vector3], vì vậy tôi thậm chí không cần để khởi tạo nó về 0 '" . Đó là nơi thông tin của tôi đến từ. Nhưng bây giờ nghe lại, anh chỉ nói "thường". Điểm tiếp theo ngay trong bài thuyết trình là JIT hành xử khác với trình gỡ lỗi được đính kèm, ảnh hưởng đến hiệu suất (bạn đã kiểm tra như thế nào?). Ngoài ra: anh ấy đang nói về JIT ở đây, vì vậy có lẽ IL vẫn "tốt" (có thể kiểm chứng?).
Andrew Russell

IL đã được kiểm tra thông qua Reflector và các bài kiểm tra đã được chạy bên ngoài IDE được xây dựng trong Bản phát hành (trên Windows, tôi không còn tư cách thành viên CC để kiểm tra)
Jason Kozak

1
Dựa trên điều này - tôi tự hỏi liệu sẽ tốt hơn (và sẽ tốt hơn bao nhiêu) để làm cho những thành viên tạm thời đó static(và / hoặc tích cực hơn sử dụng lại chúng). Như vậy, chẳng hạn, Bodylớp học trong Farseer có khoảng 73 thành viên nổi "không cần thiết".
Andrew Russell

-1

Câu hỏi hay. Tôi là một anh chàng C # /. NET khá sắc sảo và có một chút thành tích, và đây có vẻ là một quyết định thiết kế khá kỳ lạ đối với tôi. Điều đầu tiên nhảy ra với tôi là mã này không có cách nào an toàn. Tôi không biết đó có phải là sự cố trong hệ thống Vật lý hay không, nhưng lưu trữ dữ liệu tạm thời ngoài phạm vi của phương pháp thường là một công thức cho thảm họa.

Thành thật mà nói, nếu tôi thường xuyên gặp loại mã này trong khung của bên thứ ba, có lẽ tôi sẽ cố gắng tìm một khung khác.


3
Không thực sự trả lời câu hỏi.
Brian Ortiz

Vâng, điều tốt nhất tôi có thể làm là xác nhận rằng anh ta không điên, và dường như không có bất kỳ lợi ích thực sự nào mà nó được mã hóa theo cách đó. Việc tìm hiểu mục đích thực sự là hỏi anh chàng đã viết mã :).
Mike Strobel

Cảm ơn, Mike. Tôi bắt đầu nghi ngờ rằng nhà phát triển ban đầu là người điên, không phải tôi. Nhưng nó luôn giúp kiểm tra;)
Andrew Russell

An toàn luồng đôi khi có thể là một sự đảm bảo tốn kém để cung cấp, đặc biệt là khi viết thư viện nặng tính toán FP cho một nền tảng không sử dụng các hướng dẫn SIMD.
Jason Kozak

-1

Về cơ bản, GC trên 360 chỉ thực hiện các bộ sưu tập GEN 2, đắt tiền, do đó các biến tạm thời được tạo và xóa mọi khung hình (như các đối tượng tạm thời) khiến toàn bộ các bộ sưu tập chạy, sẽ giết chết hiệu suất rất nhanh.

Tôi nghi ngờ họ đã làm theo cách này để tái sử dụng đối tượng đó và không thu thập được nó.


1
Điều này cũng xảy ra với tôi, nhưng các thành viên tạm thời có vẻ là loại giá trị, vì vậy dù sao họ cũng sẽ không được phân bổ vào đống được quản lý.
Mike Strobel

2
Phải, nhưng chỉ khi họ là thành viên trong lớp. Nếu họ là người địa phương (phạm vi phương thức), họ sẽ được phân bổ trên ngăn xếp. Câu hỏi là tại sao họ không đơn giản đi theo con đường đó.
Mike Strobel

1
@Blair - Theo MSDN ( msdn.microsoft.com/en-us/l Library / bb203912.aspx ) Xbox360 sử dụng .NET Compact Framework. Có vẻ như sự khác biệt trong GC có liên quan đến điều đó, vì vậy tôi theo đuổi điều đó để nghiên cứu thêm về vấn đề này.
Logan Kincaid

1
@Blair: @Logan Kincaid là chính xác. Bộ sưu tập rác của CF hoạt động khác với khung thông thường. Có một bài nói chuyện hay về chủ đề trong XNA Game Studio 3.0 Unleashed - tuy nhiên cuốn sách đó sẽ sớm bị lỗi thời với việc phát hành 4.0.
Steven Evers

1
@Blair: Do môi trường bộ nhớ hạn chế của 360 (và hầu hết các thiết bị được nhắm mục tiêu thông qua CF), nên sử dụng Mark & ​​Sweep GC. Do đó, rất nhiều phân bổ nhỏ sẽ kích hoạt bộ sưu tập và thời gian thu thập có liên quan đến # tham chiếu. Rất nhiều chi tiết tại đây: download.microsoft.com/.../Mobility/
Kẻ
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.