gpt4 book ai didi

c++ - 我可以使用 cmpxchg16b 以原子方式将指针复制到指针和 int,同时递增 int(原子引用计数)吗?

转载 作者:太空狗 更新时间:2023-10-29 21:20:21 25 4
gpt4 key购买 nike

我的目标是复制指针并以原子方式增加引用计数器,无需锁定。我可以使用 cmpxchg16b,还是有更简单的方法?我对汇编程序一无所知,所以请原谅任何明显的错误。

编辑:类似this的东西,但对于这种英特尔架构。 (我仍在尝试看看我是否可以将 dr. dobbs 文章中的内容适应我的平台。原子操作似乎有点不同)

示例内存

struct MyThing {
void * pSomeObj;
uint64_t counter;
__attribute__((aligned(16)));
};

我想做的就是这样。

MyThing* globalSource = ...;

...
MyThing* dest;
//copy the pointer while incrementing counter all in one shot. (to prevent data race where a copy is done and some other thread deletes the pointer before the the counter gets a chance to be updated)
AtomicCopyAndIncrement(dest, globalSource);

从逻辑上讲,这就是我想要完成的:

bool AtomicCopyAndIncrement(MyThing *dest, MyThing *src) {
//begin atomic
dest = src;
dest->counter++;
//end atomic
return true;
}

此函数按原样交换所有内容。我认为是对的。

bool AtomicSwap(MyThing *dest, MyThing *src)
{
bool swap_result;
__asm__ __volatile__
(
"lock cmpxchg16b %0;"
"setz %3;"

: "+m" (*dest), "+a" (dest->pSomeObj), "+d" (dest->counter), "=q" (swap_result)
: "b" (src->pSomeObj), "c" (src->counter)
: "cc", "memory"
);
return swap_result;
}

此函数应获取 src 并将其设置为等于 dest,同时递增在 dest 中分配的计数器。

bool AtomicCopyAndIncrement(MyThing *dest, MyThing *src)
{
bool swap_result;
__asm__ __volatile__
(
"lock cmpxchg16b %0;"
"setz %3;"
//all wrong
: "+m" (*dest), "+a" (dest->pSomeObj), "+d" (dest->counter), "=q" (swap_result)
: "b" (src->pSomeObj), "c" (src->counter +1)
: "cc", "memory"
);
return swap_result;
}

这会减少计数器,但会将点复制回自身。我不知道这是否有必要, 但我认为这是正确的。 edit 我很确定这是错误的。

bool AtomicDecrement(MyThing *dest)
{
bool swap_result;
__asm__ __volatile__
(
"lock cmpxchg16b %0;"
"setz %3;"

: "+m" (*dest), "+a" (dest->pSomeObj), "+d" (dest->counter), "=q" (swap_result)
: "b" (dest->pSomeObj), "c" (dest->counter -1)
: "cc", "memory"
);
return swap_result;
}

使用场景是这样的:

线程 0:

MyThing* newThing;
do {
if (newThing) delete newThing;
newThing = new MyThing;
newThing->pSomeObj->SomeUpdate();
}
while (AtomicSwap(newThing, globalThing));
//then deal with the memory in newThing

线程 1-N:

MyThing *currentThing = new MyThing;
//make currentThing->pSomeObj the same as globalThing->pSomeObj, and increment the counter
AtomicCopyAndIncrement(currentThing, globalThing);

最佳答案

考虑使用 std::atomic。如果目标体系结构提供它,它将编译为 128 位 CAS,并且比内联汇编器更干净、更易于使用并且更独立于平台。

这是一个示例,您可以如何使用它来更新指针并以原子方式递增计数器:

std::atomic<MyThing>* target = ...;
MyThing oldValue = target->load();
MyThing newValue { newPointer, 0 };
do{
newValue.counter = oldValue.counter+1;
while(target->compare_exchange_strong(oldValue,newValue))

关于c++ - 我可以使用 cmpxchg16b 以原子方式将指针复制到指针和 int,同时递增 int(原子引用计数)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24726460/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com