问题描述
我是SIMD编程的新手,所以请问一个明显的问题.
I'm new to SIMD programming, so please excuse me if I'm asking an obvious question.
我做了一些实验,以至于想要将SIMD值存储在动态分配的结构中.
I was experimenting a bit and got to a point where I want to store a SIMD value in a dynamically allocated structure.
代码如下:
struct SimdTest
{
__m128 m_simdVal;
void setZero()
{
__m128 tmp = _mm_setzero_ps();
m_simdVal = tmp; // <<--- CRASH ---
}
};
TEST( Plane, dynamicallyAllocatedPlane )
{
SimdTest* test = new SimdTest();
test->setZero();
delete test;
}
执行标有CRASH注释的方法时,代码将崩溃,并具有以下异常:
When the method marked with CRASH comment is executed, the code crashes with the following exception:
Unhandled exception at 0x775315de in test-core.exe: 0xC0000005: Access violation reading location 0x00000000
有人可以解释一下为什么分配操作会中断,以及应该如何动态分配包含SIMD的对象以使其正常工作?
Could someone please explain why does the assignment operation break, and how should SIMD-containing objects be allocated dynamically so that they work fine?
我需要补充的是,如果我静态实例化SimdTest对象并调用setZero方法,则一切正常.
I need to add that if I statically instantiate a SimdTest object and call the setZero method, everything works fine.
谢谢,帕克萨斯(Paksas)
Thanks,Paksas
推荐答案
之所以死亡,是因为结构未对齐.CRT分配器仅承诺此处需要对齐8、16.您需要在MSVC上使用_aligned_malloc()以获得正确对齐的堆分配内存.
It dies because the structure is mis-aligned. The CRT allocator only promises alignment to 8, 16 is required here. You'll need to use _aligned_malloc() on MSVC to get properly aligned heap allocated memory.
两种解决方法.由于这是一个POD结构,因此您可以进行以下转换:
Two ways to go about it. Since this is a POD struct, you could just cast:
#include <malloc.h>
...
SimdTest* test = (SimdTest*)_aligned_malloc(sizeof SimdTest, 16);
test->setZero();
_aligned_free(test);
或者您可以覆盖该结构的new/delete运算符:
Or you could override the new/delete operators for the struct:
struct SimdTest
{
void* operator new(size_t size) { return _aligned_malloc(size, 16); }
void operator delete(void* mem) { return _aligned_free(mem); }
// etc..
};
这篇关于SIMD和动态内存分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!