2012-11-01 25 views
78

Cách để có được bộ đếm an toàn chủ đề trong C# với hiệu suất tốt nhất có thể là gì?C# Chủ đề an toàn nhanh (est) truy cập

này cũng đơn giản như nó được:

public static long GetNextValue() 
{ 
    long result; 
    lock (LOCK) 
    { 
     result = COUNTER++; 
    } 
    return result; 
} 

Tuy nhiên, có giải pháp thay thế nhanh hơn?

Trả lời

20

tôi đề nghị bạn sử dụng được xây dựng trong increment khóa liên động của .NET trong thư viện System.Threading.

Đoạn mã dưới đây sẽ tăng một biến dài bằng cách tham khảo và hoàn toàn chủ đề an toàn:

Interlocked.Increment(ref myNum); 

Nguồn: http://msdn.microsoft.com/en-us/library/dd78zt0c.aspx

66

Theo đề xuất của người khác, Interlocked.Increment sẽ có hiệu suất tốt hơn so với lock(). Chỉ cần nhìn vào IL và Assembly nơi bạn sẽ thấy rằng Increment biến thành một tuyên bố "bus lock" và biến của nó được tăng lên trực tiếp (x86) hoặc "added" (x64).

Tuyên bố "khóa buýt" này khóa bus để ngăn một CPU khác truy cập vào bus trong khi CPU gọi hoạt động. Bây giờ, hãy xem IL của C# lock(). Tại đây, bạn sẽ thấy các cuộc gọi đến Monitor để bắt đầu hoặc kết thúc một phần.

Nói cách khác, câu lệnh .Net lock() đang hoạt động nhiều hơn .Net Interlocked.Increment.

SO, nếu tất cả những gì bạn muốn làm là tăng biến, Interlock.Increment sẽ nhanh hơn. Xem lại tất cả các phương pháp được lồng vào nhau để xem các hoạt động nguyên tử khác nhau có sẵn và để tìm những hoạt động phù hợp với nhu cầu của bạn. Sử dụng lock() khi bạn muốn thực hiện những điều phức tạp hơn như nhiều lần tăng/giảm liên quan đến nhau hoặc để tuần tự hóa các tài nguyên phức tạp hơn số nguyên.

+0

Upvote để thêm ngữ cảnh – fsimonazzi

+0

-1 cho chi tiết triển khai. Đúng là khóa là chậm hơn so với op nguyên tử, nhưng điều này không liên quan gì đến IL. Các cuộc gọi hàm đó sẽ nhanh hơn một op nguyên tử nếu không phải cho ngữ nghĩa của chúng, vốn không phải là yêu cầu của IL. – Puppy

Các vấn đề liên quan