Tôi muốn giảm thiểu đồng bộ hóa và viết mã không có khóa khi có thể trong dự án của tôi. Khi hoàn toàn cần thiết tôi muốn thay thế spinlocks trọng lượng nhẹ được xây dựng từ các hoạt động nguyên tử cho pthread và win32 mutex khóa. Sự hiểu biết của tôi là đây là các cuộc gọi hệ thống bên dưới và có thể gây ra một chuyển đổi ngữ cảnh (có thể không cần thiết cho các phần rất quan trọng mà chỉ cần quay vài lần là thích hợp hơn).Spinlocks trọng lượng nhẹ được chế tạo từ các hoạt động nguyên tử GCC?
Các hoạt động nguyên tử tôi đề cập đến cũng là tài liệu ở đây: http://gcc.gnu.org/onlinedocs/gcc-4.4.1/gcc/Atomic-Builtins.html
Dưới đây là một ví dụ để minh họa cho những gì tôi đang nói về. Hãy tưởng tượng một cây RB với nhiều độc giả và nhà văn có thể. RBTree :: exist() là chỉ đọc và thread an toàn, RBTree :: insert() sẽ yêu cầu truy cập độc quyền bởi một nhà văn duy nhất (và không có độc giả) để được an toàn. Một số mã:
class IntSetTest
{
private:
unsigned short lock;
RBTree<int>* myset;
public:
// ...
void add_number(int n)
{
// Aquire once locked==false (atomic)
while (__sync_bool_compare_and_swap(&lock, 0, 0xffff) == false);
// Perform a thread-unsafe operation on the set
myset->insert(n);
// Unlock (atomic)
__sync_bool_compare_and_swap(&lock, 0xffff, 0);
}
bool check_number(int n)
{
// Increment once the lock is below 0xffff
u16 savedlock = lock;
while (savedlock == 0xffff || __sync_bool_compare_and_swap(&lock, savedlock, savedlock+1) == false)
savedlock = lock;
// Perform read-only operation
bool exists = tree->exists(n);
// Decrement
savedlock = lock;
while (__sync_bool_compare_and_swap(&lock, savedlock, savedlock-1) == false)
savedlock = lock;
return exists;
}
};
(cho phép giả định nó không cần phải ngoại lệ an toàn)
Là mã này thực sự thread-an toàn không? Có bất kỳ ưu/khuyết điểm nào đối với ý tưởng này không? Lời khuyên nào? Việc sử dụng spinlocks như thế này là một ý tưởng tồi nếu các chủ đề không thực sự đồng thời?
Xin cảm ơn trước. ;)
Câu trả lời tôi đưa ra trong một câu hỏi tương tự, http://stackoverflow.com/questions/1919135/critical-sections-that-spin-on-posix/1923218#1923218, có thể sẽ có liên quan ở đây. –
Câu trả lời của bạn chắc chắn liên quan đến vấn đề sử dụng khóa spinlocks nói chung. Họ có vẻ như một ý tưởng tốt cho các máy smp trong trường hợp điển hình. Tình huống xấu nhất (một nhà văn ngừng chạy trong phần quan trọng) thậm chí với trường hợp có nhiều khả năng của hai luồng đồng thời cố gắng chèn cùng một lúc? Điều gì về trong một môi trường luồng lai mà các luồng người dùng được ánh xạ lên một số luồng hạt nhân bằng với số lượng bộ xử lý logic trên máy? Tình huống xấu nhất sẽ ít xảy ra hơn; Không? – Thomas
Tôi không chắc chắn mức độ mà số lượng các chuỗi hạt nhân ảnh hưởng đến khả năng chạy vào các vấn đề hiệu suất. Có thể là người viết luồng đã sử dụng hết phần thời gian của nó giữa mục nhập và lối ra của khóa, điều này sẽ dẫn đến trường hợp vấn đề cho dù có bao nhiêu luồng hạt nhân. Vào thời điểm này, tôi sẽ lưu ý rằng hoạt động chèn RB-tree là O (log (n)), do đó cây càng lớn thì vấn đề này càng xảy ra. Ngoài ra, một cây lớn hơn có nhiều khả năng gây ra lỗi trang trong khi cập nhật, điều này cũng sẽ khiến cho trường hợp sự cố xảy ra nhiều hơn. Tôi muốn tránh spinlocks ở đây. –