tôi thấy mã spinlock sau trong boost::smart_ptr
:sự khác biệt giữa pthread_spinlock và tăng :: smart_ptr :: spinlock?
bool try_lock()
{
return (__sync_lock_test_and_set(&v_, 1) == 0);
}
void lock()
{
for (unsigned k=0; !try_lock(); ++k)
{
if (k<4)
; // spin
else if (k < 16)
__asm__ __volatile__("pause"); // was ("rep; nop" ::: "memory")
else if (k < 32 || k & 1)
sched_yield();
else
{
struct timespec rqtp;
rqtp.tv_sec = 0;
rqtp.tv_nsec = 100;
nanosleep(&rqtp, 0);
}
}
}
void unlock()
{
__sync_lock_release(&v_);
}
Vì vậy, nếu tôi hiểu điều này một cách chính xác, khi khóa được tranh luận các chủ đề đến theo cấp số nhân sẽ back-off, đầu tiên quay một cách hoang dại, sau đó dừng lại, sau đó năng suất thời gian còn lại thời gian của nó lát, và cuối cùng lật-flopping giữa ngủ và năng suất.
Tôi cũng đã tìm thấy cài đặt glibc pthread_spinlock
, sử dụng lắp ráp để thực hiện khóa.
#define LOCK_PREFIX "lock;" // using an SMP machine
int pthread_spin_lock(pthread_spinlock_t *lock)
{
__asm__ ("\n"
"1:\t" LOCK_PREFIX "decl %0\n\t"
"jne 2f\n\t"
".subsection 1\n\t"
".align 16\n"
"2:\trep; nop\n\t"
"cmpl $0, %0\n\t"
"jg 1b\n\t"
"jmp 2b\n\t"
".previous"
: "=m" (*lock)
: "m" (*lock));
return 0;
}
Tôi sẽ thừa nhận rằng sự hiểu biết của tôi về lắp ráp không tốt, vì vậy tôi không hiểu đầy đủ về những gì đang xảy ra ở đây. (Ai đó có thể vui lòng giải thích điều này đang làm gì?)
Tuy nhiên, tôi chạy một số xét nghiệm so với tăng spinlock và glibc pthread_spinlock, và khi có nhiều lõi hơn đề, mã tăng nhanh hơn so với mã glibc.
Mặt khác, Khi có nhiều hơn chủ đề nhiều hơn lõi, mã glibc là tốt hơn.
Tại sao điều này? Sự khác biệt giữa hai triển khai spinlock này làm cho chúng hoạt động khác nhau trong từng kịch bản là gì?
Hài hước, tôi đã thực hiện một thử nghiệm tương tự cách đây vài năm và nhận được kết luận tương tự: 'pthread_spin_lock' hiệu quả hơn so với vòng quay thủ công (dòng từ tăng) khi có nhiều tranh chấp. –