多个线程可以对数组中的不同字节进行“原子”无锁写入吗?
Posted
技术标签:
【中文标题】多个线程可以对数组中的不同字节进行“原子”无锁写入吗?【英文标题】:Can multiple threads do "atomic" lockfree writes to different bytes in an array? 【发布时间】:2021-09-10 09:20:43 【问题描述】:N
线程可以在M
x
-bit 元素的数组中执行长度为k
x
-bit 元素的非重叠间隔的“原子”无锁写入(最多N
M
)?
例如。假设N
是10
,M
是10
,k
是1,x
是8
。
然后我们有10
线程,10
字节数组,每个线程将1
字节写入数组。 (根据假设,每个线程写入一个不同的字节,因为间隔是不重叠的。)
这是一个测试这是否可能的程序,或者一个线程是否“踩到他邻居的脚趾”。
/*
t gcc-8 bytes1.c -o bytes1 -lpthread && t ./bytes1
*/
#include <stdint.h>
typedef uint8_t u8;
typedef int32_t i32;
typedef int64_t i64;
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
// ----------------------------------------------------------------------------------------------------------------------------#
/* @blk1 test if multiple threads can do 1-byte aligned lockfree atomic writes to an array! */
#define THRS_TEST_LOCKFREE_WRITES_DX 0x20
#define THRS_TEST_LOCKFREE_WRITES_TMUL 2 // thread multiplier (for the numbre of threads)!
typedef struct
i32 idx;
i32 tdim;
pthread_t pthr;
i32 dx;
u8* g_data;
thr_t;
void* thr_test_lockfree_write(void* arg)
thr_t* thr = (thr_t*)arg;
for(int i=0; i<thr->dx; ++i)
thr->g_data[thr->idx*thr->dx + i] = thr->idx;
return NULL;
void thrs_test_lockfree_writes()
i32 thrs_idim = THRS_TEST_LOCKFREE_WRITES_TMUL * sysconf(_SC_NPROCESSORS_ONLN);
thr_t* thrs = alloca(sizeof(thr_t)*thrs_idim);
i32 x_dx = THRS_TEST_LOCKFREE_WRITES_DX;
i64 x_idim = x_dx*thrs_idim;
u8* x_data = aligned_alloc(0x1000, sizeof(u8)*x_idim);
for(int i=0; i<thrs_idim; ++i)
thrs[i].idx = i;
thrs[i].tdim = thrs_idim;
thrs[i].dx = x_dx;
thrs[i].g_data = x_data;
pthread_create(&thrs[i].pthr, NULL, thr_test_lockfree_write, &thrs[i]);
for(int i=0; i<thrs_idim; ++i)
pthread_join(thrs[i].pthr, NULL);
putchar(0x0a);
for(int i=0; i<x_idim/x_dx; ++i)
printf("\x1b[32m%02x\x1b[91m/\x1b[37m%02x \x1b[0m", i,thrs_idim-1);
i32 flag = 1;
for(int j=0; j<x_dx; ++j)
printf("%02x", x_data[i*x_dx+j]);
flag &= x_data[i*x_dx+j]==i%0x100;
printf(" %d\n",flag);
free(x_data);
// ----------------------------------------------------------------------------------------------------------------------------#
int main()
thrs_test_lockfree_writes();
puts("\nbye!");
【问题讨论】:
【参考方案1】:N 个线程能否执行“原子”无锁写入
在可以将单个字节写入内存的架构上(这是所有现代架构),是的。
另请参阅this answer,并注意,由于false sharing,您的程序实际实现的并行度将远低于预期。
【讨论】:
这很有趣。根据article,多线程代码 with 错误共享有时可能比串行代码没有错误共享慢(尽管我希望这是主要适用于罕见的退化情况,例如一遍又一遍地更新同一个字节)。 @étale-cohomology,许多特定于并行代码的性能损失在某些情况下会产生如此大的影响,以至于相同任务的串行代码可以与之相比。以上是关于多个线程可以对数组中的不同字节进行“原子”无锁写入吗?的主要内容,如果未能解决你的问题,请参考以下文章