由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - 再来一个实战问题:可以避免使用atomic吗?
进入Programming版参与讨论
1 (共1页)
b***i
发帖数: 3043
1
有这样一个线程,里面在读取一个数据,这个读取过程read是需要时间的,1秒之内,
blocking。现在需要实现一个函数free_read,要立刻返回最新的数据,不能等待。由
于编译器可能乱序,一般是用atomic来实现内存屏障,避免写入数组和修改下表两个操
作乱序。现在我的实现是想避免atomic,我的方案是否可行?原来的atomic是否解决多
线程读取的问题?
float values[2];
// std::atomic read_from = 0;
unsigned char read_from = 0;
// background thread to write
void worker() {
while(true) {
// 原来是
// values[1 - read_from] = read();
// read_from = 1 - read_from;
values[1 - (readfrom++ % 2)] = read();
}
}
int free_read() {
return values[read_from];
}
int main(){
values[read_from] = read();
std::thread background(worker);
// now we can read any time we want
std::thread 1... sleep, read, sleep read
std::thread 2... sleep, read, sleep read
return 0;
}
b***i
发帖数: 3043
2
这俩能乱序吗?我怎么觉得不可能啊
values[1 - read_from] = read();
read_from = 1 - read_from;

【在 b***i 的大作中提到】
: 有这样一个线程,里面在读取一个数据,这个读取过程read是需要时间的,1秒之内,
: blocking。现在需要实现一个函数free_read,要立刻返回最新的数据,不能等待。由
: 于编译器可能乱序,一般是用atomic来实现内存屏障,避免写入数组和修改下表两个操
: 作乱序。现在我的实现是想避免atomic,我的方案是否可行?原来的atomic是否解决多
: 线程读取的问题?
: float values[2];
: // std::atomic read_from = 0;
: unsigned char read_from = 0;
: // background thread to write
: void worker() {

m*****n
发帖数: 3575
3
你说的问题在数据库很常见,即写要原子性的写,而读可以不原子性,随便几个线程都
可以。
理论上讲,你做一个单独管写的锁,读不限制。
b***i
发帖数: 3043
4
我觉得写就一个while循环,不需要原子,本来浮点数写就原子的。while里面访问那个
下标有读有写,这两个是不可能乱序的。
读的时候只要是最新的就行。至于读的时候又来更新的,其实这个条件下读到具体哪个
不重要,都是最新的。

【在 m*****n 的大作中提到】
: 你说的问题在数据库很常见,即写要原子性的写,而读可以不原子性,随便几个线程都
: 可以。
: 理论上讲,你做一个单独管写的锁,读不限制。

m*****n
发帖数: 3575
5
所以你要确保锁是只锁写的
当然如果是累加,还得更复杂
那叫update,从读到写,或者是先写后读,都得锁
否则就会出现并列第几的问题

【在 b***i 的大作中提到】
: 我觉得写就一个while循环,不需要原子,本来浮点数写就原子的。while里面访问那个
: 下标有读有写,这两个是不可能乱序的。
: 读的时候只要是最新的就行。至于读的时候又来更新的,其实这个条件下读到具体哪个
: 不重要,都是最新的。

m*****p
发帖数: 39
6
誰告訴你浮點數咚闶窃拥模br />
回去複習一下現代處理器架構的microops、
interconnect、load/store unit、ooo

【在 b***i 的大作中提到】
: 我觉得写就一个while循环,不需要原子,本来浮点数写就原子的。while里面访问那个
: 下标有读有写,这两个是不可能乱序的。
: 读的时候只要是最新的就行。至于读的时候又来更新的,其实这个条件下读到具体哪个
: 不重要,都是最新的。

b***i
发帖数: 3043
7
我用的是float

【在 m*****p 的大作中提到】
: 誰告訴你浮點數咚闶窃拥模br />
: 回去複習一下現代處理器架構的microops、
: interconnect、load/store unit、ooo

b****h
发帖数: 2105
8
readfrom++自身就不是atomic,更何况还要写和读数组1-readfrom。这不仅仅是编译乱
序,还有runtime cpu之间的race

【在 b***i 的大作中提到】
: 有这样一个线程,里面在读取一个数据,这个读取过程read是需要时间的,1秒之内,
: blocking。现在需要实现一个函数free_read,要立刻返回最新的数据,不能等待。由
: 于编译器可能乱序,一般是用atomic来实现内存屏障,避免写入数组和修改下表两个操
: 作乱序。现在我的实现是想避免atomic,我的方案是否可行?原来的atomic是否解决多
: 线程读取的问题?
: float values[2];
: // std::atomic read_from = 0;
: unsigned char read_from = 0;
: // background thread to write
: void worker() {

b***i
发帖数: 3043
9
我说的是我原来的方案,不需要++.就是1楼里面写的注释里面的:原来是那组。这玩意
儿能乱序吗?
float values[2];
unsigned char read_from = 0;
// background thread to write
void worker() {
while(true) {
values[1 - read_from] = read();
read_from = 1 - read_from;
}
}
int free_read() {
return values[read_from];
}
int main(){
values[read_from] = read();
std::thread background(worker);
// now we can read any time we want
std::thread 1... sleep, read, sleep read
std::thread 2... sleep, read, sleep read
return 0;
}
编译器可能把代码变成
x = readfrom
readfrom = x
values[x] = read();
所以需要atomic来加入内存屏障吗?

【在 b****h 的大作中提到】
: readfrom++自身就不是atomic,更何况还要写和读数组1-readfrom。这不仅仅是编译乱
: 序,还有runtime cpu之间的race

1 (共1页)
进入Programming版参与讨论