2017-02-26 12 views
0

정렬 된 메모리와 정렬되지 않은 메모리에서 데이터를 읽는 SSE 명령어 _mm_loadu_si128을 사용하여 정렬되지 않은 두 벡터 vec1vec2의 정수를 읽습니다. 그런 다음 비트 단위 및 연산을 수행하고 정렬되지 않은 메모리에 데이터를 저장하는 _mm_storeu_si128을 사용하여 결과를 저장합니다. 저장소의 대상은 arr1이라는 배열입니다. 저장소 전에는 arr1에 액세스 할 수 있지만 arr1에 액세스하는 저장소는 정의되지 않은 동작을 제공합니다 (때로는 segfaults).배열에 저장 한 후 정의되지 않은 동작

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

arr1의 "구조 변화", 나는 가게 후 액세스 할 수없는 이유이다 _mm_storeu_si128인가?

+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이 벡터의 요소를 가리키고 있다는 의미는 아니며, itselft 벡터를 가리 킵니다. 나중에 (__m128i*) (p_vec1 + k)을 읽는 것은 정의되지 않은 동작입니다. p_vec1 + 1이 벡터의 두 번째 값을 가리 키지 않습니다. vec1 다음의 벡터를 가리키고 있습니다 (어떤 의미가 없습니다).

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

그래서 p_vec1p_vec2이 벡터의 내용을 가리키는됩니다

당신은 아마의 라인을 따라 뭔가를 원하는 것입니다.