我有两段代码,桌面上有32个核心。
代码A使用32个线程并执行以下操作,
1)将值写入内存中的某些随机位置 2)以原子方式向全局变量添加值。
代码B使用16个线程将值写入随机位置,并使用另外16个线程以原子方式将值添加到全局变量。
我想知道为什么代码B在每秒对全局变量执行的原子操作数量方面更快。
这是代码A
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%' :
+--------------------------+-----------------+
| Variable_name | Value |
+--------------------------+-----------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| collation_connection | utf8_general_ci |
| collation_database | utf8_unicode_ci |
| collation_server | utf8_unicode_ci |
+--------------------------+-----------------+
这是代码B
var a uint64 = 0
const N = 10 * 1024 * 1024
var data [N]uint64
func main() {
for i := 0; i < 32; i ++ {
go func(id int) {
source := rand.NewSource(int64(id))
local_rand := rand.New(source)
for {
atomic.AddUint64(&a, uint64(1))
data[local_rand.Int31n(N)] = uint64(1)
}
}(i)
}
var b uint64 = 0
for {
c := atomic.LoadUint64(&a)
fmt.Println(c - b)
b = c
time.Sleep(time.Second)
}
}
答案 0 :(得分:1)
原子操作很昂贵。为了保持原子性,您需要确保对该代码块的互斥执行。通常这是通过加载链接,存储条件等指令实现的。在代码A中,您有32个原子操作,但在代码B中,您只有16个。原子工作减少,执行时间缩短!
作为一个实验,尝试使用代码A中的内存操作来改变原子操作的顺序。(先做内存然后再做原子操作)。你应该看到执行时间缩短了。