内存未正确对齐?

时间:2013-06-06 18:40:18

标签: c++ memory-management sse

我正在尝试在SSE中使用对齐操作,我遇到了问题(惊喜)。

typedef struct _declspec(align(16)) Vec4 {  
    float x;  
    float y;  
    float z;  
    float w;  
};

Vec4 SSE_Add(const Vec4 &a, const Vec4 &b) {  
    _declspec(align(16)) Vec4 return_val;  

    _asm { 
        MOV EAX, a                    // Load pointers into CPU regs
        MOV EBX, b

        MOVAPS XMM0, [EAX]            // Move unaligned vectors to SSE regs
        MOVAPS XMM1, [EBX]

        ADDPS XMM0, XMM1              // Add vector elements
        MOVAPS [return_val], XMM0     // Save the return vector
    }

    return return_val;
}

我在return return_val收到了访问冲突。这是对齐问题吗?我怎么能纠正这个?

2 个答案:

答案 0 :(得分:2)

我发现问题出在EBX寄存器上。如果你推/弹EBX,那么它的工作原理。我不知道为什么,所以如果有人能解释一下 - 请做。

编辑:我查看了反汇编,在函数的开头,它将堆栈指针存储在EBX中:

mov ebx, esp

所以你最好确保不要失去它。

答案 1 :(得分:0)

这有点依赖编译器......写的不正确:     movaps return_val,xmm0

为什么不向我们展示生成的代码?

你写这篇文章的方式比你让编译器独自完成它要糟糕得多。

  • 这个函数应该是无限的,并且在最好的情况下转换为单个指令,如果你这样写它就不能内联。
  • 此函数可以在Intel 64的寄存器中接收其参数,并将其结果返回到寄存器中,如果您这样写,则强制使用堆栈。
  • 此函数可以使用返回值优化,这样写就会强制您将xmm0写入return_val变量,该变量必须再次复制。

所以...对齐与未对齐的MOVPS是你最不关心的问题。

为什么不在便携式代码中编写:

inline void add(const float *__restrict__ a, const float *__restrict__ b, float *__restrict__ r)
{
    for (int i = 0; i != 4; ++i) r[i] = a[i] + b[i];
}