为什么store_idx_x86()的汇编输出与store_idx()相同,load_idx_x86()的汇编输出与load_idx()相同?
我理解__atomic_load_n()将刷新核心的失效队列,而__atomic_store_n()将刷新核心的存储缓冲区。
注意——我遵守了:gcc(GCC) 4.8.2 20140120(Red Hat 4.8.2-16)
更新:我明白x86永远不会重新排序存储与其他存储以及加载与其他加载——那么gcc是否足够聪明地只在需要时实现sfence和lfence,或者使用__atomic_会产生栅栏(假设内存模型比__ATOMIC_RELAXED更严格)?
代码
我理解__atomic_load_n()将刷新核心的失效队列,而__atomic_store_n()将刷新核心的存储缓冲区。
注意——我遵守了:gcc(GCC) 4.8.2 20140120(Red Hat 4.8.2-16)
更新:我明白x86永远不会重新排序存储与其他存储以及加载与其他加载——那么gcc是否足够聪明地只在需要时实现sfence和lfence,或者使用__atomic_会产生栅栏(假设内存模型比__ATOMIC_RELAXED更严格)?
代码
#include <stdint.h>
inline void store_idx_x86(uint64_t* dest, uint64_t idx)
{
*dest = idx;
}
inline void store_idx(uint64_t* dest, uint64_t idx)
{
__atomic_store_n(dest, idx, __ATOMIC_RELEASE);
}
inline uint64_t load_idx_x86(uint64_t* source)
{
return *source;
}
inline uint64_t load_idx(uint64_t* source)
{
return __atomic_load_n(source, __ATOMIC_ACQUIRE);
}
汇编:
.file "util.c"
.text
.globl store_idx_x86
.type store_idx_x86, @function
store_idx_x86:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
movq %rsi, -16(%rbp)
movq -8(%rbp), %rax
movq -16(%rbp), %rdx
movq %rdx, (%rax)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size store_idx_x86, .-store_idx_x86
.globl store_idx
.type store_idx, @function
store_idx:
.LFB1:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
movq %rsi, -16(%rbp)
movq -8(%rbp), %rax
movq -16(%rbp), %rdx
movq %rdx, (%rax)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size store_idx, .-store_idx
.globl load_idx_x86
.type load_idx_x86, @function
load_idx_x86:
.LFB2:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq (%rax), %rax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2:
.size load_idx_x86, .-load_idx_x86
.globl load_idx
.type load_idx, @function
load_idx:
.LFB3:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq (%rax), %rax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE3:
.size load_idx, .-load_idx
.ident "GCC: (GNU) 4.8.2 20140120 (Red Hat 4.8.2-16)"
.section .note.GNU-stack,"",@progbits
(uint64_t*)&myArrayOfChar[3]
),因此我不认为这是安全的;除非你滥用"实现定义"(关于指针类型转换)作为一个"意外但在技术上允许摧毁你整整一周"行为的可怜借口(这似乎是GCC开发者变得喜欢的东西)。 - Brendan