如果你是在写实际代码,那么都用atomic或加锁来保护就完事了,不要想着能有太多trick可以搞事情
如果只是问理论,这事要分很多情况来看
硬件层,因为你只说了64位,但我对其他的也不熟,就拿x86_64来说,这个int64的8字节应该是对齐且不跨cacheline的,一般cacheline是64byte,所以只要8字节对齐就ok了(也许不对齐也行,具体得查下资料,但不能跨cacheline),不过go的话,应该每个正常变量都是给你对齐的,除非你先申请了一个数组,然后在不对齐的位置unsafe.Pointer去转了一把,这个就不讨论了,默认你是正常代码
然后如果不用atomic或加锁,并且也没有触发其他的同步时机(比如创建go程什么的),可能出现的情况有两种:
一个是比较极端的情况,你的这个go程在反复读写这个变量且中间没有做其他特别的事情,而编译器将整个变量的读写优化成寄存器操作了,并且没有写回内存,那这时候等于就是执行你这个go程的cpu自己在玩
另一个是你的写操作的确执行了对内存的写,或者虽然有一些步骤是被优化成了读写寄存器,但是触发了往内存写的动作,比如需要调用函数了,或当前函数return了,或操作了一个较复杂的计算过程寄存器不够用了等等,但这时候也不保证你写到“内存”的值能被其他线程看到,因为你可能只是写到cpu的cache中,至于什么时候刷到主存,对不起没保证,也不保证什么时候同步给其他cpu(也许过一小会吧,但请不要依赖未保证的东西),所以即便是执行了写内存的指令,其他go程若在其他cpu执行,也可能看不到“最新”的值
所以实际代码用atomic或加锁就行了,它们是一定会保证写操作的结果让大家都可见的