在问及DPDK为何是高性能时,答案基本上都是DMA,零拷贝,hugepage,PMD轮询,以及无锁等。所以无锁结构的性能有多高呢。
DPDK无锁结构的实现
在dpdk中,无锁的结构的思路基本是这样的:
#operate n size burst
do{
copy r->head_ptr -> local_head
local_head +n -> local_next
success = atomic32_cas(&r->head_ptr,local_head,local_next)
}while(success == 0)
//operate the n size burst
这是dpdk ring中无锁的核心实现。主要做了三件事情:
1. 将ring中的标记位复制到本地
2. 对本地的标记位先进行一次移位,并计算出自己占用完空间后,新的标记位应该指向的位置。
3. 原子操作CAS(compare and set), 比较本地标记位和ring中的标记位,如果相等,将ring中的标记位设置为local_next。否则回退到1.
可以看到,实际上这还是一个锁。他锁在CAS这个操作。这个原子操作如果失败了,则说明在123步的时候,有另外的线程对ring进行了操作,需要进行回退。这是一个最小粒度的锁。在多并发的时候,能够最小化等待的时间。
DPDK无锁测试结果
DPDK中提供了一个test程序来进行测试。
这个test 程序是$RTE_SDK/$RTE_TARGET/app/test
。
test->输入ring_perf_autotest
结果:
RTE>>ring_perf_autotest
### Testing single element and burst enq/deq ###
SP/SC single enq/dequeue: 11
MP/MC single enq/dequeue: 47
SP/SC burst enq/dequeue (size: 8): 4
MP/MC burst enq/dequeue (size: 8): 9
SP/SC burst enq/dequeue (size: 32): 3
MP/MC burst enq/dequeue (size: 32): 4
### Testing empty dequeue ###
SC empty dequeue: 2.41
MC empty dequeue: 3.30
### Testing using a single lcore ###
SP/SC bulk enq/dequeue (size: 8): 4.64
MP/MC bulk enq/dequeue (size: 8): 9.54
SP/SC bulk enq/dequeue (size: 32): 3.45
MP/MC bulk enq/dequeue (size: 32): 4.62
### Testing using two hyperthreads ###
SP/SC bulk enq/dequeue (size: 8): 15.40
MP/MC bulk enq/dequeue (size: 8): 24.20
SP/SC bulk enq/dequeue (size: