2016-06-29 4 views
0

uint8_t *를 허용하는 CUDA 커널 기능이 있습니다. 이 uint8_t * 배열의 특정 위치에 계산 된 부동 소수점을 쓰려고합니다 (포인터 시작 위치 이후 12 바이트).uint8_t * 위치에 float 쓰기

이 작업을 수행하는 올바른 방법은 무엇입니까? 나는 가정하면 :

uint8_t* ptr = address of a properly initialized and allocated memory segment 

그런 다음 다음은 충돌에 커널을 발생합니다

float some_float = ... 
*((float *) (ptr+12)) = some_float 

나는 이것이 아마, 일부 어쩌면 가짜 싶어서이 일을 올바른 방법이 아니다 알고 .. 하지만 누군가는 이것에 대해 가장 잘하는 방법에 대한 팁이나 두 가지를 줄 수 있습니다.

감사합니다.

+0

테스트 됨 - 배열이 제대로 초기화되면 충돌이 발생하지 않아야합니다. 이 짧은 코드는 충돌하지 않고 올바른 결과를 출력합니다 : 'float num; uint8_t arr [4]; uint8_t * ptr = & arr [0]; num = 14; * ((float *) (ptr)) = num; num = * ((float *) (ptr)); ' – xinaiz

+0

[MCVE] (https://stackoverflow.com/help/mcve)를 제공해주십시오. – Xiobiq

+0

'ptr'가'sizeof (float)'주소로 나눌 수있는 좋은 점을 가리키지 않는다면 정렬 문제가 발생할 수 있습니다. 그러나 [mcve]를 요구하는 군중에 가입합니다. – user4581301

답변

-2

어떻게 float 값을 작성합니까?

다른 데이터 크기를 가진 여러 객체를 처리하는 프로젝트에서 이미 작업하고 있습니다. 우리는 체인 목록에 객체 속성을 유지하려고하지만 하나의 커다란 공통 버퍼에 데이터를 저장합니다. 따라서이 버퍼에는 8 비트 부호있는 정수와 32 비트 부동 소수점, 부호없는 정수 64 비트 등이 있습니다. 분명히 아무도 공간을 절약하기 위해 정렬 된 첫 번째 요소를 제외하고는 없습니다. 우리가 값을 기록 할 때 그래서 우리가 할 :

// Write float value to any position in your big buffer 
float fValueToWrite = 10; 
memcpy(ptr + 12, &fValueToWrite, sizeof(fValueToWrite)); 

우리는 우리가 할 값을 읽고 자하는 경우 : 트릭 비에서 읽기에 대해 걱정하지 않는다 방어 적이기을 사용

// Read the float from any unalign position of your big buffer 
float fReadValue = 0; 
memcpy(&fReadValue, ptr + 12, sizeof(fReadValue)); 

단어 경계.

그러나 우리는 읽을 이런 짓을하는 경우 :

float buffer[256] = {0};` 
uint8_t* ptr = (uint8_t *)buffer; 
float fCrashReadValue = *((float *)(ptr + 11)); 

이 (권자 실제로는 소수의) (11)에 의해 경계 나누어 읽는 지원하지 않는 프로세서에 정렬 오류가 발생할 수 있습니다. 따라서 CPU가이 경우 32 비트 인 경우 ptr이 할당 된 버퍼를 가리키고 제대로 정렬되지 않은 다른 포인터를 가리키는 경우 12이 유효한 경계가됩니다.

내가 경험 한 많은 ARM 프로세서는 경계가 아닌 주소를 사용하여 오류가 발생할 것이라고 말할 수 있습니다. 그러나 x86 (Intel) 프로세서는 조용히 페널티 성능을 재편성합니다.

희망 사항 :

+0

나는 거기에 정확성을 보았고,'memcpy'는 이것을 끄집어내는 좋은, 안전한 방법이지만, 나머지는 잘못된 말로 착각하거나, 또는 두 가지를 조합 한 것입니다. – user4581301

관련 문제