嗨伙计,
首先对不起,这将是一个适度长的帖子。所以,请耐心阅读。
在这里,我将介绍一些我学到的概念,同时略读一些关于无锁编程的文章,并对这种学习表示怀疑。
另外,讨论的内容是* NIX多处理器平台。
首先说“LOCKLESS = BLOCKLESS”,因为据说整个线程系统都会取得进展,因为CAS / DCAS只有在某些线程取得进展时才会失败。
所以,我们可以说,在这里,如果在互斥锁上阻塞,我们正在旋转/等待一个条件(例如CAS的while循环)。
Quest1 > How would spinning on a while loop be more efficient than blocking on a
mutex ?
Quest2 > A good design employing mutexes also ensure that system progresses, so
isnt that BLOCKLESS too by definition?
作为问题1的答案,人们会争辩说阻塞可能会进入内核等待,并且可能存在可能代价高昂的上下文切换。任何进一步的清晰度将是值得赞赏的。
好吧,假设在得到前两个问题的答案之后,我将确信在完成原子操作不是很大/耗时时,我认为无锁是非常快速和实时的。<登记/>
Quest3 > So, isnt lock-free something like spinlock ? If yes, why cant we use
pthread spin lock ?
接下来,在网上提供的大多数文献中,人们都会看到像这样的原子操作的实现:
__asm__ __volatile__("lock\nxadd" X " %0,%1" : "=r"(result),"=m"(*(T *)i_pAddress) : "0"(i_addValue) : "memory"); // What does this mean ? Memory Fencing ?
Quest4 > Does ":memory" in the above assemble mean memory fencing ? If yes,
doesnt that take around 100 cycles to implement ?
Quest5 > Doesnt the lock instruction here assert that the operation is being
done on a shared resource, thus other threads are blocking here ?
As far as I know
this question is not valid for the more or less recent Intel multi proc arch
as the locking is done on cache lines.
提前致谢。
答案 0 :(得分:2)
无锁以某种方式使用某些自旋锁。但是当我们将自旋称为锁时,我们通常希望同步大块代码。当我们谈论无锁时,它会针对一个任务,通常只有一个指令。第一个在长时间做的时候旋转,第二个在做空的时候旋转。第一个继续旋转,第二个“旋转”仅仅是“重试”。
如果我没有弄错,“内存”意味着不要将内存变量优化为寄存器变量。(不太正确。确切地说,它告诉编译器必须强烈地命令内存的使用。但它有与硬件内存防护无关。)
锁定指令不如非锁定指令快,但仍然比上下文切换快。但它速度较慢,所以通常在写一个旋转的东西时,我们会首先进行非锁定测试。如果它通过,我们将做锁定的。
答案 1 :(得分:2)
这是很多问题!
如何在while循环中旋转比在互斥锁上阻塞更有效?
如果资源基本上没有扩展,平均而言你不必长时间旋转。这可能比使用互斥锁更便宜。
使用互斥锁的好设计也可以确保系统的进步,所以定义的BLOCKLESS也不是这样吗?
线程等待可能更公平。如果在等待资源时旋转,“不幸”线程可能需要等待很长时间。
那么,像spinlock一样没有锁定吗?如果是,为什么我们不能使用pthread自旋锁?
如果您对如何使算法无锁定有一个好主意,您可能根本不需要旋转。
以上汇编中的“:memory”是否意味着内存屏障?如果是,那么实施大约需要100个周期吗?
是的,它是需要它的系统上的内存防护。同步大量CPU缓存会花费很长时间(可能超过100个时钟)。另一方面,自旋锁或互斥锁也需要记忆栅栏才能正常工作。
这里的lock指令是否断言操作是在共享资源上完成的,因此其他线程在这里阻塞?
这是一种不同类型的阻止,可能在硬件级别。如果其他线程需要您刚刚更新的数据,则需要等待其 CPU上的数据。