Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 使用内部函数的SSE2程序集溢出_Assembly_Intrinsics_Sse2 - Fatal编程技术网

Assembly 使用内部函数的SSE2程序集溢出

Assembly 使用内部函数的SSE2程序集溢出,assembly,intrinsics,sse2,Assembly,Intrinsics,Sse2,我不熟悉SSE和SSE2,我编写了一个小的C示例(分配两个计数器,一个增加,另一个减少,而不是添加两个),该示例按预期工作。我使用了微软的Visual Studio 10 C++快车。作为第二步,我想了解引擎盖下发生了什么,但我现在感到困惑。 例如,For循环中的赋值操作编译为: __m128i a_ptr = _mm_load_si128((__m128i*)&(a_aligned[i])); mov eax,dword ptr [i] mov

我不熟悉SSE和SSE2,我编写了一个小的C示例(分配两个计数器,一个增加,另一个减少,而不是添加两个),该示例按预期工作。我使用了微软的Visual Studio 10 C++快车。作为第二步,我想了解引擎盖下发生了什么,但我现在感到困惑。 例如,For循环中的赋值操作编译为:

__m128i a_ptr = _mm_load_si128((__m128i*)&(a_aligned[i]));
 mov         eax,dword ptr [i]  
 mov         ecx,dword ptr [a_aligned]  
 movdqa      xmm0,xmmword ptr [ecx+eax*2]  
 movdqa      xmmword ptr [ebp-1C0h],xmm0  
 movdqa      xmm0,xmmword ptr [ebp-1C0h]  
 movdqa      xmmword ptr [a_ptr],xmm0  
据我所知,前两行获取对齐的地址的组件,第三行将其复制到xmm0寄存器。但我不明白为什么它会被复制回内存,而不是再次复制到xmm0(而不是a_ptr)。我认为_mm_load_si128内在函数应该将对齐[I]的128位复制到xmm0,仅此而已。为什么会这样?理论上我错了吗?如果不是,我应该如何提示编译器?我的示例代码正确吗(从没有不必要之处的意义上讲)? 以下是我的完整示例代码:

#include <xmmintrin.h>
#include <emmintrin.h>
#include <iostream>

int main(int argc, char *argv[]) {
    unsigned __int16 *a_aligned = (unsigned __int16 *)_mm_malloc(32 * sizeof(unsigned __int16),16);
    unsigned __int16 *b_aligned = (unsigned __int16 *)_mm_malloc(32 * sizeof(unsigned __int16),16);
    unsigned __int16 *c_aligned = (unsigned __int16 *)_mm_malloc(32 * sizeof(unsigned __int16),16);

    for(int i = 0; i < 32; i++) {
        a_aligned[i] = i;
        b_aligned[i] = i;
        c_aligned[i] = 0;
    }

    for(int i = 0; i < 32; i+=8) {
        __m128i a_ptr = _mm_load_si128((__m128i*)&(a_aligned[i]));
        __m128i b_ptr = _mm_load_si128((__m128i*)&(b_aligned[i]));
        __m128i res = _mm_add_epi16(a_ptr, b_ptr);
        _mm_store_si128((__m128i*)&(c_aligned[i]), res);
    }

    for(int i = 1; i < 32; i++) {
        std::cout << c_aligned[i] << " ";
    }

    _mm_free(a_aligned);
    _mm_free(b_aligned);
    _mm_free(c_aligned);
    return 0;
}
#包括
#包括
#包括
int main(int argc,char*argv[]){
无符号整数16*a\u aligned=(无符号整数16*)mm\u malloc(32*sizeof(无符号整数16),16);
无符号uuu int16*b_ualigned=(无符号uuu int16*)mm_malloc(32*sizeof(无符号uu int16),16);
无符号uuu int16*c_ualigned=(无符号uuu int16*)mm_malloc(32*sizeof(无符号uu int16),16);
对于(int i=0;i<32;i++){
a_对齐的[i]=i;
b_对齐[i]=i;
c_对齐[i]=0;
}
对于(int i=0;i<32;i+=8){
__m128i a_ptr=_mm_load_si128((_m128i*)和(a_aligned[i]);
__m128i b_ptr=_mm_载荷_si128((_m128i*)和(b_对齐[i]);
__m128i res=_mm_add_epi16(a_ptr,b_ptr);
_mm_store_si128((u m128i*)和(c_aligned[i]),res;
}
对于(int i=1;i<32;i++){

std::cout在编译器设置中启用优化(使用发行版配置而不是调试).

内部函数被明确设计为帮助编译器代码生成器更好地优化代码。您正在查看调试配置生成的汇编代码。这不是优化的代码。请查看发布版本中的代码:

        __m128i a_ptr = _mm_load_si128((__m128i*)&(a_aligned[i]));
011D10A0  movdqa      xmm0,xmmword ptr [eax] 
        __m128i b_ptr = _mm_load_si128((__m128i*)&(b_aligned[i]));
011D10A4  movdqa      xmm1,xmmword ptr [edx+eax] 
        __m128i res = _mm_add_epi16(a_ptr, b_ptr);
011D10A9  paddw       xmm0,xmm1 
        _mm_store_si128((__m128i*)&(c_aligned[i]), res);
011D10AD  movdqa      xmmword ptr [ecx+eax],xmm0 

看起来好多了,不是吗?

谢谢你,你的答案和斯蒂芬·卡农的答案一样有用,但他是第一个回答的人。是的,当你努力记录答案时就会出现这种情况。这不是问题,其他人可能会发现它很有用。每个人都会遇到这种情况,不要担心。