所以我尝试使用SSE函数__mm_load_128
,我对SSE fo非常新,如果我在某处犯了一些愚蠢的错误,请原谅我。_declspec(align(16))不会将指针对齐到16字节
这里是Visual Studio中的代码
void one(__m128i *arr, char *temp)
{
// SSE needs 16 byte alignment.
_declspec (align(16)) __m128i *tmp = (__m128i*) temp;
if (((uintptr_t)tmp & 15) == 0)
printf("Aligned pointer");
else
printf("%d", ((uintptr_t)tmp & 15)); // This prints as 12
arr[0] = _mm_load_si128(tmp);
}
我得到一个错误 0xC0000005: Access violation reading location 0xFFFFFFFF.
0xFFFFFFFF
看起来不正确的,我在做什么错。
arr
参数初始化为_m128i arr[5] = { 0 }
替代方法是使用_mm_loadu_128
其工作正常,但据我所知,这应该产生movdqu
指令但这是组件产生
arr[0] = _mm_loadu_si128(tmp);
00D347F1 mov eax,dword ptr [tmp]
00D347F4 movups xmm0,xmmword ptr [eax]
00D347F7 movaps xmmword ptr [ebp-100h],xmm0
00D347FE mov ecx,10h
00D34803 imul edx,ecx,0
00D34806 add edx,dword ptr [arr]
00D34809 movups xmm0,xmmword ptr [ebp-100h]
00D34810 movups xmmword ptr [edx],xmm0
谢谢你们,从答案中我发现我犯了几个错误。
校准源使用
_alinged_malloc
编译与优化。
使用C++蒙上不是C
你没有做任何事情来对齐源地址。您正在尝试对齐指针而不更改存储的地址。你应该确保'temp'指向的缓冲区正确对齐。你也应该避免在C++代码中使用C风格的转换。 – VTT
@VTT:'(__m128i *)'是内在函数的标准样式。 'reinterpret_cast <__m128i*>(temp)'通常太笨重了,英特尔的内部函数已经有足够长的名字了。 (另外,'__m128i'可以用来别名,所以它很特殊。) –
如果你希望看起来像asm的输出,不要编译时禁用优化。发出'imul edx,ecx,0'只是一个让'edx'归零的好方法。它正在执行一个'movups'加载,但是之后又会溢出到临时堆栈上并重新加载(对齐加载),然后再次存储到实际需要结果的位置。就像我说的,如果你希望asm看起来像你在编写C++时想象的那样,那么启用优化。 –