【发布时间】:2011-10-05 23:08:13
【问题描述】:
在测试程序的可伸缩性时,我遇到了必须将 memcpy 操作设为 atomic operation 的情况。我必须将 64 字节的数据从一个位置复制到另一个位置。
我遇到了一种解决方案,即使用旋转变量是:
struct record{
volatile int startFlag;
char data[64];
volatile int doneFlag;
};
伪代码如下
struct record *node;
if ( node->startFlag ==0 ) { // testing the flag
if( CompareAndSwap(node->startFlag , 0 ,1 ) ) { // all thread tries to set, only one will get success and perform memcpy operation
memcpy(destination,source,NoOfBytes);
node->doneFlag = 1; // spinning variable for other thread, those failed in CompAndSwap
}
else {
while ( node->doneFlag==0 ) { // other thread spinning
; // spin around and/or use back-off policy
}
}}
这可以作为原子 memcpy 执行吗?尽管如果执行 memcpy 的线程被抢占(在 memcpy 之前或之后但在设置 doneFlag 之前),那么其他线程将继续旋转。或者可以做些什么来使这个原子。
情况就像其他线程必须等待,除非数据被复制,因为它们必须与插入的数据、自己的数据进行比较。
在 startFlag 的情况下,我使用测试和测试和设置方法来减少一些昂贵的原子操作。
自旋锁也是可扩展的,但我测量到原子调用比自旋锁提供更好的性能,而且我正在寻找这个 sn-p 中可能出现的问题。
而且由于我使用自己的内存管理器,所以内存分配和免费调用对我来说代价高昂,所以使用另一个缓冲区并在其中复制内容,然后设置指针(因为指针大小是在原子操作下)是昂贵的,因为它会需要多次 mem-alloc 和 mem-free 调用。
编辑我没有使用互斥锁,因为它们似乎不是可扩展而且这只是程序的一部分,所以关键部分不是这么小(我知道对于较大的关键部分,很难使用原子操作)。
【问题讨论】:
-
为什么不使用合适的锁/互斥锁?
-
为什么使用 HTML 来格式化源代码?没有看到编辑器正上方的格式化相关按钮吗?
-
@phresnel:现在看到了,谢谢
标签: performance scalability atomic memcpy