英特尔处理器上的未对齐访问商店
unaligned access store on intel processor
考虑以下样本。它在标记的线上用GCC 5.4划分时我用g++ -O3 -std=c++11
编译。它在movaps
上失败了,我怀疑它执行了不一致的内存访问。可能是GCC生成如此简单的样本的非法代码,或者我缺少某些内容?我正在Intel i5-5200U上运行它。
#include <vector>
#include <memory>
#include <cstdint>
using namespace std;
__attribute__ ((noinline))
void SerializeTo(const vector<uint64_t>& v, uint8_t* dest) {
for (size_t i = 0; i < v.size(); ++i) {
*reinterpret_cast<uint64_t*>(dest) = v[i]; // Segfaults here.
dest += sizeof(uint64_t);
}
}
int main() {
std::vector<uint64_t> d(64);
unique_ptr<uint8_t[]> tmp(new uint8_t[1024]);
SerializeTo(d, tmp.get() + 6);
return 0;
}
您被6个字节踏入数组,因此现在不结盟。编译器不知道它必须避免需要对齐的说明;这就是为什么PUNNING是不确定的行为。
在C 中合法执行键入的方法很少。
魔术功能std::memcpy
是这里选择的工具:
__attribute__ ((noinline))
void SerializeTo(const vector<uint64_t>& v, uint8_t* dest) {
for (size_t i = 0; i < v.size(); ++i) {
std::memcpy(dest, std::addressof(v[i]), sizeof(v[i]));
dest += sizeof(uint64_t);
}
}
用-std=c++11 -O3 -march=native -Wall -pedantic
SerializeTo(std::vector<unsigned long, std::allocator<unsigned long> > const&, unsigned char*): # @SerializeTo(std::vector<unsigned long, std::allocator<unsigned long> > const&, unsigned char*)
mov rax, qword ptr [rdi]
cmp qword ptr [rdi + 8], rax
je .LBB0_3
xor ecx, ecx
.LBB0_2: # =>This Inner Loop Header: Depth=1
mov rax, qword ptr [rax + 8*rcx]
mov qword ptr [rsi + 8*rcx], rax
add rcx, 1
mov rax, qword ptr [rdi]
mov rdx, qword ptr [rdi + 8]
sub rdx, rax
sar rdx, 3
cmp rcx, rdx
jb .LBB0_2
.LBB0_3:
ret
https://godbolt.org/g/rega9n
相关文章:
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 如何创建一个QTableWidgetItem,用长文本右对齐,左边有省略号
- 使用 g++7 构建的代码在访问未对齐的内存时崩溃
- C++中未对齐访问的正确性
- 对齐指针的未对准访问
- 英特尔处理器上的未对齐访问商店
- 64位Windows API结构对齐导致命名管道上出现“拒绝访问”错误
- gcc是否保证对volatile整数的对齐访问是原子访问
- 如何使用指针合法地访问对齐错误的对象
- MOVAPS 访问未对齐的地址
- 对齐对数组元素的访问
- 无法访问 std::vector 的 16 位对齐成员
- 未对齐的访问导致ARM Cortex-M4出现错误
- 从字符[]访问对齐的T和的最有效方法是什么?
- 通过reinterpret_cast进行未对齐的访问
- 未对齐内存访问:它是定义的行为或不
- 在c++中声明、操作和访问未对齐内存
- 矢量化/优化循环,用于宽寄存器(特别是Xeon Phi)的未对齐数据访问
- 统一缓冲区对象未对齐.GLSL访问中断
- 为什么即使是 16 字节对齐的地址也会导致_mm_load_si128导致访问冲突