2016-10-25 1 views
0

CreateFile2 및 WriteFile을 사용하여 파일을 만들고 쓰고 나중에 16 바이트를 __m128i로 한 번에 읽은 다음에 simd 작업을 수행하는 readfile을 사용합니다. 디버그 모드에서 제대로 작동하지만 릴리스 모드에서 액세스 거부 (0xc0000005) 오류 코드가 발생합니다. 내 경험에 의하면, 16 바이트가 아닌 16 바이트짜리 물건을 16 바이트 정렬 된 물건으로 밀어 넣으려고 할 때 그런 일이 발생합니다. 그러나 16 바이트 정렬 부족으로 인해 처음에는 못생긴 머리를 낳고 있습니다.CreateFile2, WriteFile 및 ReadFile : 어떻게 16 바이트 정렬을 적용 할 수 있습니까?

#define simd __m128i 

CreateFile2() 호출에 있습니까?

_CREATEFILE2_EXTENDED_PARAMETERS extend = { 0 }; 
extend.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); 
extend.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; 
extend.dwFileFlags = /*FILE_FLAG_NO_BUFFERING |*/ FILE_FLAG_OVERLAPPED; 
extend.dwSecurityQosFlags = SECURITY_ANONYMOUS; 
extend.lpSecurityAttributes = nullptr; 
extend.hTemplateFile = nullptr; 

hMappedFile = CreateFile2(
    testFileName.c_str(), 
    GENERIC_READ | GENERIC_WRITE, 
    0, 
    OPEN_ALWAYS, 
    &extend); 

... WriteFile() 호출에서?

_OVERLAPPED positionalData; 
positionalData.Offset = 0; 
positionalData.OffsetHigh = 0; 
positionalData.hEvent = 0; 

bool writeCheck = WriteFile(
    hMappedFile, 
    &buffer[0], 
    vSize, 
    NULL, 
    &positionalData); 

... 이후 ReadFile() 호출에서?

const simd* FileNodePointer(
    _In_ const uint32_t index) const throw() 
{ 
    std::vector<simd> Node(8); 

    _OVERLAPPED positionalData; 
    positionalData.Offset = index; 
    positionalData.OffsetHigh = 0; 
    positionalData.hEvent = 0; 

    ReadFile(
     hMappedFile, 
     (LPVOID)&Node[0], 
     128, 
     NULL, 
     &positionalData); 

    return reinterpret_cast<const simd*>(&Node[0]); 
} 

여기에 16 바이트 맞춤을 적용하려면 어떻게해야합니까?

감사합니다.

+0

디버거에서 알려주는 것은 무엇입니까? 사고 현장에서 거꾸로 작업하여 문제가 발생한 지점을 찾아냅니다. – 1201ProgramAlarm

+0

캐스트를 제거하면 암시 적 변환으로 충분하고 reinterpret_cast는 위험하며 컴파일러는 코드가 단순화 될 때 평생 오류를 발견 할 가능성이 높습니다. –

답변

1

TL; DR 고전적인 "무료 사용 후"오류가 발생했습니다.


이 기능들 중 16 바이트 정렬이 필요하지 않습니다. 버퍼링이 활성화되면 정렬에 전혀 신경 쓰지 않으며 직접 I/O가 활성화 된 경우 16 바이트보다 훨씬 제한적인 페이지 정렬이 필요합니다.

데이터 버퍼가 정렬되지 않은 경우, 그렇게 만든 것입니다. 파일 I/O가 버퍼를 메모리에서 이동하지 않습니다.

그러나 액세스 위반이 전혀 정렬 문제가 발생하지 않습니다, 그것은 당신이 FileNodePointer에서 반환 허상 포인터입니다 :

자동 수명, 벡터 소멸자 실행과 벡터의 내용에 대한 포인터를의
return reinterpret_cast<const simd*>(&Node[0]); 

함수를 반환하는 동안 파일에서 방금 읽은 데이터가 들어있는 메모리를 해제합니다.

+0

메모 : 귀하의 의견은 정확하며 제시 한대로 내 코드의 문제를 해결합니다. 그러나 여기에서 문제를 해결하면 (즉, 함수가 이후에 존재하지 않는 포인터 대신 __m128i 벡터를 반환하는 경우) 여전히 동일한 액세스 위반이 발생합니다. FILE_FLAG_NO_BUFFERING을 사용하는 모델로 변경했습니다 (4096 바이트의 배수와 한 번에 4096 바이트 크기의 인덱스에서 읽기 사용). 디버그 모드에서 출력이 올바른지 확인할 수 있습니다. 그러나 릴리스 모드는 여전히 문제를 나타냅니다. 이견있는 사람? – MNagy

+0

@MNagy 예, 벡터가 깨졌습니다 (SIMD에서 필요에 맞게 오버 정렬 된 유형을 할당 할 수 없음). 파일 접근은 문제와 완전히 관련이 없습니다. –

관련 문제