본문 바로가기

NVIDIA Jetson Xavier AGX

Memory address 0x55 & 0x7f

메모리에 관련되어 아는것이 없는 상태로 연구를 진행하게 되어 최근 1달간 메모리에 대해 많은 내용을 읽었고, 그중 대부분은 동적메모리 할당(dynamic memory allocation, malloc function)에 관련된 내용이다.

 

아주 기초적인 부분들은 구글에 간단히 검색해도 많은 내용이 나오기 때문에 생략하고,

의문점들과 발견부분만 기록한다.

 

기록해야겠다 싶은 순간의 내용만을 작성할 것이기 때문에 내용이 다소 불친절할 수 있다.

이번 내용은 동적메모리를 사용할때 주로 0x55와 0x7f로 시작하는 주소가 나타나는데 이에 대한 탐구이다.

언제는 0x55로 시작하고 언제는 0x7f로 시작해서 이 상황을 한번 기록해두려 한다.


다음 구조체를 만들고 malloc을 랩핑한 xmalloc을 사용하여 동적할당 해본다.

 

<struct network>

typedef struct network {
    int *alloc1;
    int *alloc2;
    int *alloc3;
    int *alloc4;
    int *alloc5;
};

 

<malloc>

void *xmalloc(size_t size){
    void *ptr = malloc(size);
    printf("malloc: %p, size: %zd\n",ptr,size);
    return ptr;
}

 

<main>

int n = 0x2FFFF;

int main(void)
{
    struct network mal;
    int arr[n];
    size_t bytes = 0x7FFFF*sizeof(int);
    
    int i;
    for(i=0; i<n; i++){
    	arr[i]=1;
    }
    
    // 1st allocation;
    mal.alloc1 = (int*)xmalloc(bytes);
    mal.alloc2 = (int*)xmalloc(bytes);
    mal.alloc3 = (int*)xmalloc(bytes);
    mal.alloc4 = (int*)xmalloc(bytes);
    mal.alloc5 = (int*)xmalloc(bytes);
    for(i=0; i<n; i++){
    	mal.alloc1[i] = arr[i];
        mal.alloc2[i] = arr[i];
        mal.alloc3[i] = arr[i];
        mal.alloc4[i] = arr[i];
        mal.alloc5[i] = arr[i];
    }
    
    free(mal.alloc1);
    free(mal.alloc2);
    free(mal.alloc3);
    free(mal.alloc4);
    free(mal.alloc5);
    
    // 2nd allocation;
    mal.alloc1 = (int*)xmalloc(bytes);
    mal.alloc2 = (int*)xmalloc(bytes);
    mal.alloc3 = (int*)xmalloc(bytes);
    mal.alloc4 = (int*)xmalloc(bytes);
    mal.alloc5 = (int*)xmalloc(bytes);
    for(i=0; i<n; i++){
    	mal.alloc1[i] = arr[i];
        mal.alloc2[i] = arr[i];
        mal.alloc3[i] = arr[i];
        mal.alloc4[i] = arr[i];
        mal.alloc5[i] = arr[i];
    }

    free(mal.alloc1);
    free(mal.alloc2);
    free(mal.alloc3);
    free(mal.alloc4);
    free(mal.alloc5);
    
    // 3rd allocation;
    mal.alloc1 = (int*)xmalloc(bytes);
    mal.alloc2 = (int*)xmalloc(bytes);
    mal.alloc3 = (int*)xmalloc(bytes);
    mal.alloc4 = (int*)xmalloc(bytes);
    mal.alloc5 = (int*)xmalloc(bytes);
    for(i=0; i<n; i++){
    	mal.alloc1[i] = arr[i];
        mal.alloc2[i] = arr[i];
        mal.alloc3[i] = arr[i];
        mal.alloc4[i] = arr[i];
        mal.alloc5[i] = arr[i];
    }

    free(mal.alloc1);
    free(mal.alloc2);
    free(mal.alloc3);
    free(mal.alloc4);
    free(mal.alloc5);
    
    getchar();
    
    return (EXIT_SUCCESS);

}

 

(메모리 측정 방식과 값은 생략되어있다.)

위 코드의 실행으로 메모리 주소와 메모리 사용량을 측정했을 때,

1st alloc에서 다음이 출력되었다.

 

malloc: 0x7f84ab5010, size: 2097148

malloc: 0x7f848b4010, size: 2097148

malloc: 0x7f846b3010, size: 2097148

malloc: 0x7f844b2010, size: 2097148

malloc: 0x7f842b1010, size: 2097148

[AFTER MALLOC]

Total memory Usage 2827368KB (2761MB)

mCPU : 2488988KB, mGPU : 338380KB

VmData : 10472KB (10MB)

VmStk : 780KB (0MB)

[FREE MALLOC 'mal']

Total memory Usage 2823696KB (2757MB)

mCPU : 2485316KB, mGPU : 338380KB

VmData : 212KB (0MB)

VmStk : 780KB (0MB)

 

여기서 주소 아래 출력되는 내용은 /proc/meminfo와 /proc/PID/status에서 읽어온 값이다.

(mCPU는 CPU의 메모리 사용량, mGPU는 GPU의 메모리 사용량, VmData는 해당 PID의 데이터영역 메모리 사용량, VmStk은 해당 PID의 스택영역 메모리 사용량을 나타낸다.)

 

0x7f로 시작되는 주소가 나타났고 그 간격은 0x201000(dec:2,101,248)이다.

 

2nd alloc에서는 다음과 같이 나타났다.

 

malloc: 0x55a3ad60c0, size: 2097148

malloc: 0x55a3cd60d0, size: 2097148

malloc: 0x55a3ed60e0, size: 2097148

malloc: 0x55a30d60f0, size: 2097148

malloc: 0x55a32d6100, size: 2097148

[AFTER MALLOC]

Total memory Usage 2827012KB (2760MB)

mCPU : 2488632KB, mGPU : 338380KB

VmData : 10456KB (10MB)

VmStk : 780KB (0MB)

[FREE MALLOC 'mal']

Total memory Usage 2823800KB (2757MB)

mCPU : 2485420KB, mGPU : 338380KB

VmData : 216KB (0MB)

VmStk : 780KB (0MB)

 

0x55로 시작되는 주소가 나타났고 그 간격 또한 0x201000(dec:2,101,248)이다.

 

3rd alloc에서는 2nd와 동일했다.

 

malloc: 0x55a3ad60c0, size: 2097148

malloc: 0x55a3cd60d0, size: 2097148

malloc: 0x55a3ed60e0, size: 2097148

malloc: 0x55a30d60f0, size: 2097148

malloc: 0x55a32d6100, size: 2097148

[AFTER MALLOC]

Total memory Usage 2826684KB (2760MB)

mCPU : 2488304KB, mGPU : 338380KB

VmData : 10456KB (10MB)

VmStk : 780KB (0MB)

[FREE MALLOC 'mal']

Total memory Usage 2823764KB (2757MB)

mCPU : 2485384KB, mGPU : 338380KB

VmData : 216KB (0MB)

VmStk : 780KB (0MB)

 

동적 메모리 할당은 힙(heap) 영역의 낮은 메모리 주소(low memory)에서부터 높은 메모리(high memory)로 사용된다. 스택(stack) 영역은 높은 메모리주소에서 낮은 메모리주소로 할당된다.

하지만 결과에서 보듯이 0x55로 시작하는 주소는 매 할당시 주소값이 증가하며, 0x7f로 시작하는 주소는 할당되면서 주소값이 낮아진다. 왜 같은 malloc을 사용하여 동적 메모리 할당을 시켰음에도 불구하고 메모리 주소가 서로 달라지며 주소값 할당방향이 서로 달라지는것일까? 

 

코드에서 xmalloc 할당 사이즈(bytes)와 할당하는 개수(for문 횟수)는 일치하지 않는다. 할당 사이즈는 0x7FFFF이고 실제로 사용되는 개수는 0x2FFFF이다. 따라서 VmData는 10MB가 증가하지만 Total memory usage는 약 3MB밖에 증가하지 않는 것이다. 

 

 

메모리를 아주 디테일하게 분석하는것은 아직 어떻게 해야하는지 잘 모르겠다. byte 단위로 할당하면 메모리가 실제로 증가했는지 측정하기 어려워서 큰 단위(KB,MB)로 실험을 하는데 이는 매번 값이 조금씩 변한다.


누가 컴퓨터는 거짓말을 하지 않는다고 했나... 아직은 내가 모르는 원리가 많은듯 하다.

'NVIDIA Jetson Xavier AGX' 카테고리의 다른 글

Secrets of cudaMemcpyAsync delay  (0) 2021.10.29
LaneNet Install in NVIDIA Jetson Xavier AGX  (0) 2020.10.07