2013-08-06 43 views
8

Tôi đọc ở đâu đó rằng chi phí của một mutex không phải là nhiều, bởi vì bối cảnh chuyển đổi chỉ xảy ra trong trường hợp tranh chấp.Chi phí của mutex, phần quan trọng vv trên Windows

Còn được biết đến Futexes trong Linux.

Điều tương tự có giữ được tốt trong Windows không? Phần quan trọng là một bản đồ thích hợp hơn cho mutexes trong Linux.

Từ những gì tôi thu thập được, Mục quan trọng cung cấp hiệu suất tối ưu tốt hơn so với Mutex, điều này có đúng cho mọi trường hợp không?

Có trường hợp góc trong đó các mutex nhanh hơn phần quan trọng trong Windows.

Giả sử chỉ có một quá trình chủ đề được truy cập vào mutexes (Chỉ cần để loại bỏ các lợi ích khác của Phần Critical)

Added Thông tin: hệ điều hành windows Server,
Ngôn ngữ C++

+0

Tất nhiên, nếu ứng dụng của bạn có tranh chấp thường xuyên, bạn có thể suy nghĩ lại ý tưởng rằng các mutex không có nhiều chi phí. – patrickvacek

Trả lời

12

Xét mục đích cụ thể của Critical SectionsMutexes Tôi không nghĩ rằng bạn có thể đặt câu hỏi về chi phí vì bạn không có nhiều thay thế khi bạn cần nhiều chủ đề chạm vào cùng một dữ liệu. Rõ ràng, nếu bạn chỉ cần tăng/giảm số, bạn có thể sử dụng các hàm Interlocked*() trên số volatile và bạn tốt để sử dụng. Nhưng đối với bất cứ điều gì phức tạp hơn, bạn cần phải sử dụng một đối tượng đồng bộ hóa.

Bắt đầu đọc của bạn tại đây theo số Synchronization Objects available on Windows^. Tất cả các chức năng được liệt kê ở đó, được nhóm gọn và được giải thích đúng. Một số chỉ dành cho Windows 8.

Về câu hỏi của bạn, Critical Sections ít tốn kém hơn Mutexe vì chúng được thiết kế để hoạt động trong cùng một quy trình. Đọc this^this^ hoặc chỉ báo giá sau.

Một đối tượng phần quan trọng cung cấp đồng bộ hóa tương tự với đối tượng mutex, ngoại trừ một phần quan trọng chỉ có thể được sử dụng bởi các luồng của một quy trình. Các đối tượng sự kiện, mutex và semaphore cũng có thể được sử dụng trong một ứng dụng đơn, nhưng các đối tượng phần quan trọng cung cấp cơ chế đồng bộ loại trừ nhanh hơn, hiệu quả hơn một chút (một bài kiểm tra cụ thể cho bộ xử lý). Giống như một đối tượng mutex, một đối tượng phần quan trọng có thể được sở hữu bởi chỉ một luồng tại một thời điểm, điều này làm cho nó hữu ích để bảo vệ tài nguyên được chia sẻ khỏi truy cập đồng thời. Không giống như một đối tượng mutex, không có cách nào để cho biết liệu một phần quan trọng đã bị hủy bỏ hay chưa.

tôi sử dụng Critical Sections cho cùng một đồng bộ hóa quá trình và Mutexes để đồng bộ hóa giữa các quá trình.Chỉ khi tôi thực sự cần biết một đối tượng đồng bộ hóa có bị bỏ không, tôi sử dụng Mutexes trong cùng một quá trình.

Vì vậy, nếu bạn cần đối tượng đồng bộ hóa, câu hỏi không phải là chi phí nhưng rẻ hơn :) Không có sự thay thế nào khác ngoài bộ nhớ.

PS: Có thể có lựa chọn thay thế như one mentioned in the selected answer here^ nhưng tôi luôn đi cho các chức năng nền tảng cụ thể lõi vs chéo platformness. Nó luôn luôn nhanh hơn! Vì vậy, nếu bạn sử dụng Windows, sử dụng các công cụ của Windows :)

CẬP NHẬT

Dựa trên nhu cầu của bạn, bạn có thể có thể làm giảm nhu cầu của các đối tượng đồng bộ hóa bằng cách cố gắng làm càng nhiều tự chứa công việc trong một luồng nhất có thể và chỉ kết hợp dữ liệu ở cuối hoặc mọi lúc và sau đó.

Ví dụ ngu ngốc: Lấy danh sách URL. Bạn cần phải cạo chúng và phân tích chúng.

  1. Ném một loạt chủ đề và bắt đầu chọn URL, từng cái một, từ danh sách nhập liệu. Đối với mỗi một quá trình của bạn, bạn tập trung các kết quả như bạn làm điều đó. Đó là thời gian thực và mát mẻ
  2. Hoặc bạn có thể ném vào mỗi chủ đề có một phần của các URL đầu vào. Điều này loại bỏ sự cần thiết phải đồng bộ hóa quá trình lựa chọn. Bạn lưu trữ kết quả phân tích trong chuỗi và cuối cùng, bạn kết hợp kết quả chỉ một lần. Hoặc cứ 10 URL một lần thì hãy nói. Không phải cho mỗi người. Điều này sẽ làm giảm đáng kể hoạt động đồng bộ hóa.

Vì vậy, chi phí có thể được hạ xuống bằng cách chọn đúng công cụ và suy nghĩ cách hạ khóa và mở khóa. Nhưng chi phí không thể được gỡ bỏ :)

PS: Tôi chỉ nghĩ trong URL :)

UPDATE 2:

Đã nhu cầu trong một dự án để làm một số đo. Và kết quả khá bất ngờ:

  • Một std::mutex là đắt nhất. (giá của nền tảng chéo)
  • A Windows gốc Mutex là 2x nhanh hơn std.
  • A Critical Section nhanh hơn 2 lần so với gốc Mutex.
  • A SlimReadWriteLock là + -10% của Critical Section.
  • My tự chế InterlockedMutex (spinlock) là 1.25x - 1.75x nhanh hơn so với Critical Section.
+0

Tôi biết tôi không thể loại bỏ các chi phí, nhưng chỉ nghĩ rằng liệu phần quan trọng hoặc mutexes là lý tưởng cho tôi. Cảm ơn thông tin mặc dù –

+0

@DesertIce Đăng cập nhật. Đúng rồi. – CodeAngry

+1

-1 cho dễ bay hơi. Bạn không bao giờ nên dựa vào dễ bay hơi một mình cho luồng. Hoặc sử dụng nguyên tử hoặc kết hợp dễ bay hơi với hàng rào bộ nhớ. Khác, truy cập dễ bay hơi của bạn có thể kết thúc lên lại trên Linux/gcc, ví dụ. –

0

Sử dụng std :: mutex trên windows 8 Tôi thường nhận được 3-4x cải thiện (về trường hợp tranh phi) tăng tốc bằng cách sử dụng tùy chỉnh riêng đã khóa spin của tôi:

mutex dựa

auto time = TimeIt([&]() { 
for (int i = 0; i < tries; i++) { 
    bool val = mutex.try_lock(); 
    if (val) { 
     data.value = 1; 
    } 
} 

});

nhà làm khóa miễn phí

time = TimeIt([&]() { 
    for (int i = 0; i < tries; i++) { 
     if (!guard.exchange(true)) { 
      // I own you 
      data.value = 1; 
      guard.store(true); 
     } 
    } 
}); 

Các xét nghiệm được thực hiện trên x86.

Tôi chưa tìm ra điều gì std :: mutex sử dụng gạch chân trên cửa sổ vì nó tạo ra nhiều mã.