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
|