gpt4 book ai didi

c++ - 使用 SSE 操作时的内存访问冲突

转载 作者:太空狗 更新时间:2023-10-29 23:07:35 25 4
gpt4 key购买 nike

我一直在尝试重新实现一些现有的 vector 和矩阵类以使用 SSE3 命令,但每当我对 vector 数组执行一系列操作时,我似乎都会遇到这些“内存访问冲突”错误。我对 SSE 比较陌生,所以我从简单开始。这是我的 vector 类的全部内容:

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);
}

为了对我的新 vector 类与旧 vector 类进行速度测试(看看是否值得重新实现整个东西),我创建了一个简单的程序来生成一个随机的 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 变量是一个包含 SSEVector3D 类型元素的 std::vector,其组件全部初始化为 -1 之间的随机数和 1

这是我遇到的问题。如果 sseVectors 的大小为 8,191 或更小(我通过大量试验和错误得出的数字),则运行良好。如果大小为 8,192 或更大,我在尝试运行时会遇到此错误:

signal: SIGSEGV, si_code: 0 (memory access violation at address: 0x00000080)

但是,如果我在末尾注释掉该打印语句,即使 sseVectors 的大小为 8,192 或更大,我也不会收到任何错误。

我写这个 vector 类的方式有问题吗?我正在运行带有 GCC 4.6 版的 Ubuntu 12.04.1

最佳答案

首先,也是最重要的,不要这样做

__m128 * pLhs = (__m128 *) m_coords;
__m128 * pRhs = (__m128 *) rhs.m_coords;
*pLhs = _mm_add_ps(*pLhs, *pRhs);

使用 SSE,总是通过适当的内在函数显式地加载和存储,从不仅通过解除引用。不是在您的类中存储一个包含 3 个 float 的数组,而是存储一个 _m128 类型的值。这应该使编译器正确对齐您的类的实例,而不需要任何 align 属性。

但是请注意,这在 MSVC 中效果不佳。对于按值参数,MSVC 似乎通常无法满足比 8 字节对齐更强的对齐要求:-(。上次我需要将 SSE 代码移植到 Windows 时,我的解决方案是对 SSE 部分使用英特尔的 C++ 编译器而不是 MSVC...

关于c++ - 使用 SSE 操作时的内存访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12394051/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com