2017-02-26 41 views
0

我正在读取来自2个未对齐的向量vec1vec2的整数,使用SSE指令_mm_loadu_si128从对齐和未对齐的内存中读取数据。然后我进行按位操作,然后使用_mm_storeu_si128存储结果,该数据将数据存储到未对齐的内存中。该商店的目标是一个名为arr1的数组。看来在商店之前,我可以访问arr1,但在店铺访问arr1后给出了未定义的行为(有时会出现段错误)。C++ SSE:存储到数组后,未定义的行为

#include <vector> 
#include <emmintrin.h> 
#include <nmmintrin.h> 
#include <chrono> 
#include <smmintrin.h> 
#include <iostream> 

int main() 
{ 

     std::vector<uint64_t> vec1(200); 
     std::vector<uint64_t> vec2(200,1); 
     std::vector<uint64_t> *p_vec1 = &vec1; 
     std::vector<uint64_t> *p_vec2 = &vec2; 

     int total_bits = 0; 
     int k = 0; 
     for(; k < 100; k+=2){ 
       __m128i* ptr1 = (__m128i*) (p_vec1 + k); 
       __m128i* ptr2 = (__m128i*) (p_vec2 + k); 
       __m128i val1_4 = _mm_loadu_si128(ptr1); 
       __m128i val2_4 = _mm_loadu_si128(ptr2); 
       uint64_t arr1[2] = {0,0}; 
       std::cout << "val1 " << arr1[0] << std::endl; 
       _mm_storeu_si128((__m128i*) arr1, _mm_and_si128(val1_4, val2_4)); // after storing into arr1, Accessing arr1 gives undefined behavior 
       std::cout << "val2 " << arr1[0] << std::endl; // This should only output 0s but instead outputs random numbers 
       total_bits += __builtin_popcountll(arr1[0]); 
     } 
} 

_mm_storeu_si128“改变结构”的arr1,请问这是为什么我店里后不能访问它?

+1

'&vec1'为您提供'vector'对象本身的地址,而不是存储在向量中的对象。您可以尝试'uint64_t * ptr =&vec1 [0]'来获取存储的第一个值的地址。 –

+1

'uint64_t * ptr = vec1.data()'看起来更可读... – zett42

回答

4
std::vector<uint64_t> *p_vec1 = &vec1; 
std::vector<uint64_t> *p_vec2 = &vec2; 

绝对不是你想要的。这并不意味着p_vec1指向矢量中的元素,它指向矢量本身。您稍后做(__m128i*) (p_vec1 + k),其中读数是未定义的行为:p_vec1 + 1未指向矢量的第二个值;它指向vec1之后的矢量(这没有任何意义)。

你可能想沿着线的东西:

uint64_t *p_vec1 = vec1.data(); 
uint64_t *p_vec2 = vec2.data(); 

使p_vec1p_vec2都指向向量的内容。