2009-12-18 35 views
5

Tôi đang định hình trò chơi 2D XNA đơn giản của mình. Tôi thấy rằng 4% của toàn bộ thời gian chạy được thực hiện bởi operarion đơn giản của việc thêm cùng hai màu sắc, một trong số họ nhân trước bằng phao.Tối ưu hóa thao tác màu sắc trên XNA

Tôi cần gọi phương pháp này rogulthy 2000 lần cho mỗi khung hình (đối với mỗi ô trên bản đồ), cho tôi 120000 lần mỗi giây cho 60 fps của XNA. Ngay cả việc tăng tối thiểu cuộc gọi đơn lẻ cũng có thể gây ra tác động tốc độ rất lớn. Tuy nhiên, tôi đơn giản không biết làm thế nào tôi có thể làm này hiệu quả hơn

private void DoColorCalcs(float factor, Color color) 
    { 
     int mul = (int)Math.Max(Math.Min(factor * 255.0, 255.0), 0.0); 
     tile.Color = new Color(
      (byte)Math.Min(tile.Color.R + (color.R * mul/255), 255), 
      (byte)Math.Min(tile.Color.G + (color.G * mul/255), 255), 
      (byte)Math.Min(tile.Color.B + (color.B * mul/255), 255)); 

    } 

EDIT: Theo đề nghị của Michael Stum:

private void DoColorCalcs(float factor, Color color) 
    { 
     factor= (float)Math.Max(factor, 0.0); 
     tile.Color = new Color(
      (byte)Math.Min(tile.Color.R + (color.R * factor), 255), 
      (byte)Math.Min(tile.Color.G + (color.G * factor), 255), 
      (byte)Math.Min(tile.Color.B + (color.B * factor), 255)); 
    } 

này giảm thời gian sử dụng từ 4% xuống còn 2,5%

+2

Từ bạn đang tìm kiếm tối ưu hóa, không tối ưu hóa. :) – jalf

+0

Có vẻ như rất nhiều cuộc gọi cho một trò chơi 2D đơn giản. Thay vào đó, bạn không thể thay đổi thuật toán tổng thể? Ví dụ: lưu trữ kết quả hoặc tránh làm mọi thứ trên mọi khung hình? – Jan

+0

Tôi cần phải tính toán lại đèn năng động cho gạch (mô hình ánh sáng của tôi bao gồm ánh sáng nhấp nháy, thay đổi cường độ ánh sáng theo tỷ lệ Sin (thời gian) * 0,1 cho từng ô trong mỗi khung hình) – PiotrK

Trả lời

1

Câu hỏi đầu tiên của tôi là tại sao điểm nổi? Nếu bạn chỉ cần mở rộng màu để làm mờ chúng, bạn không cần nhiều độ chính xác. Ví dụ:

int factorTimes256; 
tile.Color.R = Math.Max(255, tile.Color.R + (color.R * factorTimes256)/256); 
// same for G and B 

Nói cách khác, thể hiện hệ số của bạn dưới dạng số nguyên từ 0 đến 256 và thực hiện tất cả các tính toán trên số nguyên. Bạn không cần độ chính xác cao hơn 8 bit vì kết quả chỉ là 8 bit.

Câu hỏi thứ hai của tôi là, bạn có nói rằng bạn đã đi từ 4% đến 2,5% trong mã này? Đó là nhỏ. Những người sử dụng profilers chỉ làm thiết bị đo đạc hoặc lấy mẫu bộ đếm chương trình thường hài lòng với những cải tiến nhỏ như vậy. Tôi đặt cược bạn có những thứ khác xảy ra mà mất nhiều thời gian hơn, mà bạn có thể tấn công. Here's an example of what I mean.

1

Các cải thiện rõ ràng sẽ là bao gồm phép chia (/ 255) trong việc tính toán mul, để giảm phân chia từ 3 xuống một bộ phận đơn lẻ:

private void DoColorCalcs(float factor, Color color) 
{ 
    float mul = Math.Max(Math.Min(factor * 255.0f, 255.0f), 0.0f)/255f; 
    tile.Color = new Color(
     (byte)Math.Min(tile.Color.R + (color.R * mul), 255), 
     (byte)Math.Min(tile.Color.G + (color.G * mul), 255), 
     (byte)Math.Min(tile.Color.B + (color.B * mul), 255)); 
} 

đó đang được nói, vì bạn đang thay thế tile.Color, nó thực sự có thể nhanh hơn để thay thế nó tại chỗ thay vì ghi đè lên nó (mặc dù tôi muốn hồ sơ này để xem nếu nó giúp):

private void DoColorCalcs(float factor, Color color) 
{ 
    float mul = Math.Max(Math.Min(factor * 255.0f, 255.0f), 0.0f)/255f; 
    tile.Color.R = (byte)Math.Min(tile.Color.R + (color.R * mul), 255); 
    tile.Color.G = (byte)Math.Min(tile.Color.G + (color.G * mul), 255); 
    tile.Color.B = (byte)Math.Min(tile.Color.B + (color.B * mul), 255); 
} 

Điều này ngăn cản tính toán lại kênh alpha và có thể giảm số lượng lệnh một chút.

+0

(int) Math.Max ​​(Math.Min (yếu tố * 255.0, 255.0) , 0,0)/255 sẽ dẫn đến 0 trong hầu hết các trường hợp. Vì vậy, điều này không giúp đỡ. –

+0

Đồng ý với Simon Ottenhaus - bạn đang chia số nguyên 0..255 x 255 cho bạn 254 số 0 và giá trị đơn "one" – PiotrK

+0

Ah, tôi quên - tôi đã cố gắng thay thế tạo đối tượng Màu mới bằng cách đặt biến của nó. Nó đòi hỏi một chút "phương pháp tiếp cận xấu" như tôi đã phải thay đổi tile.Color từ loại Accessor để biến. Nhưng nó vẫn không có tác động tốc độ (kiểm tra và làm tròn kết quả đến 0,1 khung hình/giây) – PiotrK