【发布时间】:2012-09-05 19:41:08
【问题描述】:
我一直在尝试重新实现一些现有的向量和矩阵类以使用 SSE3 命令,每当我对向量数组执行一系列操作时,我似乎都会遇到这些“内存访问冲突”错误。我对 SSE 比较陌生,所以我从简单开始。这是我的矢量类的全部内容:
class SSEVector3D
{
public:
SSEVector3D();
SSEVector3D(float x, float y, float z);
SSEVector3D& operator+=(const SSEVector3D& rhs); //< Elementwise Addition
float x() const;
float y() const;
float z() const;
private:
float m_coords[3] __attribute__ ((aligned (16))); //< The x, y and z coordinates
};
所以,还没有发生很多事情,只是一些构造函数、访问器和一个操作。使用我(诚然有限)的 SSE 知识,我实现了加法操作如下:
SSEVector3D& SSEVector3D::operator+=(const SSEVector3D& rhs)
{
__m128 * pLhs = (__m128 *) m_coords;
__m128 * pRhs = (__m128 *) rhs.m_coords;
*pLhs = _mm_add_ps(*pLhs, *pRhs);
return (*this);
}
为了快速测试我的新矢量类与旧矢量类(看看是否值得重新实现整个东西),我创建了一个简单的程序,它生成一个随机的 SSEVector3D 对象数组并将它们加在一起。没什么太复杂的:
SSEVector3D sseSum(0, 0, 0);
for(i=0; i<sseVectors.size(); i++)
{
sseSum += sseVectors[i];
}
printf("Total: %f %f %f\n", sseSum.x(), sseSum.y(), sseSum.z());
sseVectors 变量是一个 std::vector,包含 SSEVector3D 类型的元素,其组件全部初始化为 -1 和 1 之间的随机数。
这是我遇到的问题。如果sseVectors 的大小为8,191 或更小(我通过大量试验和错误得出的数字),则运行良好。如果大小为8,192 或更大,我在尝试运行时会收到此错误:
信号:SIGSEGV,si_code:0(地址内存访问冲突:0x00000080)
但是,如果我在最后注释掉该打印语句,即使 sseVectors 的大小为 8,192 或更大,我也不会收到错误。
我编写这个向量类的方式有问题吗?我正在运行带有 GCC 4.6 版的 Ubuntu 12.04.1
【问题讨论】:
-
见:How is a vector's data aligned?(另外,第一个问题写得很好,+1。)
-
您遇到了段错误,因为 STL 容器未与 SSE 对齐。
8192发生的奇怪现象只是内存分配器中的一个伪影,它会影响返回指针的对齐方式。 -
我认为要考虑的一个重要问题是
_mm_add_ps()例程正在加载多少数据,也许更关键的是,有多少数据被写回。这与浮点数组的实际大小有何关系?我认为这个问题的答案至少会指出三个问题——错误的计算结果、对齐问题和数组溢出...... -
谢谢,我没有意识到这一点。我想这会带来另外几个问题:
-
1) 这是否意味着每个使用 SSEVector3D 对象的数据结构和类也需要正确对齐?以及 Vector3D 的每个 std::vector 吗? [编辑:好吧,我想这不是“几个”问题,它只是一个!]
标签: c++ ubuntu vector sse sse3