Main Content

MATLAB의 메모리 할당 방식

이 항목에서는 변수를 사용할 때 MATLAB®이 메모리를 할당하는 방법에 대한 정보를 제공합니다. MATLAB이 내부적으로 데이터를 처리하는 방법 등과 같은 이러한 정보는 향후 릴리스에서 변경될 수 있습니다.

배열의 메모리 할당

숫자형 배열이나 문자형 배열을 변수에 대입하면 MATLAB은 연속 메모리 블록을 할당하고 이 블록에 배열 데이터를 저장합니다. MATLAB은 또한 배열의 클래스와 차원 등, 배열 데이터에 대한 정보를 헤더라는 별도의 작은 메모리 블록에 저장합니다. 대부분의 배열에서 헤더를 저장하는 데 필요한 메모리는 미미한 정도입니다. 하지만 대규모 데이터 세트를 많은 수의 작은 배열 대신 적은 수의 큰 배열에 저장하면 몇 가지 이점이 있을 수 있습니다. 배열 수가 적을수록 필요한 배열 헤더도 적어지기 때문입니다.

기존 배열에 새 요소를 추가하는 경우, MATLAB은 저장소가 연속되도록 유지하는 방식으로 메모리의 배열을 확장합니다. 일반적으로 이렇게 하려면 확장된 배열을 수용할 만큼 크기가 충분한 새 메모리 블록을 찾아야 합니다. 그러면 MATLAB은 원래 위치에서 이 새 메모리 블록으로 배열의 내용을 복사하고, 이 블록의 배열에 새 요소를 추가하고, 원래 배열이 있던 위치의 메모리를 해제합니다.

기존 배열에서 요소를 제거하는 경우, MATLAB은 삭제된 요소를 제거한 후 원래 메모리 위치에서 해당 저장소를 축약하여 메모리 저장소가 연속되도록 유지합니다.

배열 복사하기

배열을 두 번째 변수에 대입하면(예를 들어, B = A를 실행하는 경우) MATLAB은 새 메모리를 즉시 할당하지 않습니다. 대신, 배열 참조의 복사본을 만듭니다. AB에서 참조하는 메모리 블록의 내용을 수정하지 않는 한, 두 개 이상의 데이터 복사본을 저장할 필요가 없습니다. 하지만, A 또는 B를 사용하여 메모리 블록의 요소를 수정하면 MATLAB이 새 메모리를 할당하고 데이터를 이 메모리로 복사한 후 생성된 복사본을 수정합니다.

Windows® 시스템에서는 memory 함수를 사용하여 메모리 세부 정보를 조사할 수 있습니다. Windows 시스템에서 배열 복사가 메모리 사용량에 미치는 영향을 보기 위해 현재 폴더의 파일에 함수 memUsed를 만듭니다. 이 함수는 memory를 호출하여 MATLAB 프로세스가 사용하는 메모리 양을 메가바이트 단위로 반환합니다.

function y = memUsed
usr = memory;
y = usr.MemUsedMATLAB/1e6;

memUsed를 호출하여 현재 메모리 사용량을 표시합니다.

format shortG
memUsed
ans = 
       3966.1

2000×2000 숫자형 배열을 만들고 메모리 사용량의 변화를 관찰합니다. 이 배열은 약 32MB의 메모리를 사용합니다.

A = magic(2000);
memUsed
ans = 
       3998.1

BA의 복사본을 만듭니다. 배열 데이터의 복사본을 두 개 만들 필요가 없기 때문에, MATLAB은 배열 참조의 복사본만 하나 만듭니다. 여기에는 많은 양의 추가 메모리가 필요하지 않습니다.

B = A;
memUsed
ans = 
       3998.1

이제 절반의 행을 제거하여 B를 수정합니다. AB가 더 이상 동일한 데이터를 가리키지 않기 때문에 MATLAB은 별도의 메모리 블록을 B에 할당해야 합니다. 그 결과, MATLAB 프로세스에서 사용하는 메모리의 양이 B의 크기(A에 필요한 32MB의 절반인 약 16MB)만큼 증가합니다.

B(1001:2000,:) = [];
memUsed
ans = 
       4014.1

함수 인수

MATLAB은 함수 호출에서 전달된 인수를 복사되는 배열을 처리하는 것과 동일한 방식으로 처리합니다. 변수를 함수에 전달할 때, 실제로는 해당 변수가 나타내는 데이터에 대한 참조를 전달하는 것입니다. 호출된 함수에 의해 데이터가 수정되지 않는 한, 호출하는 함수의 변수와 호출된 함수의 변수는 메모리에서 동일한 위치를 가리킵니다. 호출된 함수가 입력 데이터의 값을 수정하는 경우 MATLAB은 원래 변수의 복사본을 메모리 내의 새 위치에 만들고, 수정된 값으로 이 복사본을 업데이트한 다음, 호출된 함수의 입력 인수가 이 새 위치를 가리키게 합니다.

예를 들어, 함수 myfun을 살펴보겠습니다. 이는 이 함수에 전달된 배열의 값을 수정합니다. MATLAB은 메모리의 새 위치에 A의 복사본을 만들고, 변수 X를 이 새 복사본에 대한 참조로 설정한 다음, X의 행 하나를 0으로 설정합니다. A가 참조하는 배열은 변경되지 않은 상태로 유지됩니다.

A = magic(5);
myfun(A)

function myfun(X)
X(4,:) = 0;
disp(X)
end

호출하는 함수가 myfun에 전달한 배열의 수정된 값을 필요로 하는 경우에는, 업데이트된 배열을 호출된 함수의 출력값으로 반환해야 합니다.

데이터형과 메모리

메모리 요구 사항은 MATLAB 데이터형에 따라 다릅니다. 사용자는 MATLAB에서 다양한 데이터형을 처리하는 방식을 학습하여 코드에 사용되는 메모리의 양을 줄일 수 있습니다.

숫자형 배열

MATLAB에서는 부호 있는(그리고 부호 없는) 8비트, 16비트, 32비트, 64비트 정수에 각각 1, 2, 4, 8바이트를 할당합니다. MATLAB은 배정밀도(double) 형식 또는 단정밀도(single) 형식으로 부동소수점 숫자를 나타냅니다. MATLAB은 4바이트를 사용하여 single형 숫자를 저장하므로, 이 숫자는 8바이트를 사용하는 double형 숫자보다 더 적은 메모리를 필요로 합니다. 그러나, single형 숫자는 더 적은 비트를 사용하여 저장되므로 double형 숫자보다 작은 정밀도로 표현됩니다. double은 MATLAB의 디폴트 숫자 데이터형으로, 대부분의 계산 작업에 필요한 충분한 수준의 정밀도를 제공합니다. 자세한 내용은 부동소수점 숫자(Floating-Point Number) 항목을 참조하십시오.

구조체 및 셀형 배열

숫자형 배열은 연속 메모리 블록에 저장해야 하는 반면, 구조체와 셀형 배열은 연속되지 않은 블록에 저장될 수 있습니다. 구조체와 셀형 배열의 경우, MATLAB은 배열에 대해서뿐 아니라 구조체의 각 필드 또는 셀형 배열의 각 셀에 대해서도 헤더를 만듭니다. 따라서, 구조체나 셀형 배열을 저장하는 데 필요한 메모리 양은 구조체나 셀형 배열에 포함된 데이터의 크기뿐 아니라 구조체나 셀형 배열이 생성된 방식에 따라서도 달라집니다.

예를 들어, 필드 R, G, B를 가지며 각 필드가 100×50 배열을 포함하는 스칼라 구조체 S1이 있다고 가정해 보겠습니다. S1에는 전체 구조체를 설명하는 헤더 하나, 각각의 고유한 필드 이름에 대한 헤더 하나, 그리고 각 필드에 대한 헤더 하나가 필요합니다. 따라서 전체 구조체에 대해 총 7개의 헤더가 필요합니다.

S1.R = zeros(100,50);
S1.G = zeros(100,50);
S1.B = zeros(100,50);

반면, 각 요소가 스칼라 필드 R, G, B를 갖는 100×50 구조체형 배열 S2가 있다고 가정해 보겠습니다. 이 경우에 S2에는 전체 구조체를 설명하는 헤더 하나, 각각의 고유한 필드 이름에 대한 헤더 하나, 5,000개 요소 각각의 필드당 헤더 하나가 필요합니다. 따라서 전체 구조체형 배열에 대해 총 15,004개의 배열 헤더가 필요합니다.

for i = 1:100
    for j=1:50
        S2(i,j).R = 0;
        S2(i,j).G = 0;
        S2(i,j).B = 0;
    end
end

whos 함수를 사용하여 64비트 시스템에서 S1S2에 할당된 메모리의 양을 비교합니다. S1S2에 동일한 데이터가 포함되어 있지만, S1은 현저히 작은 메모리를 사용합니다.

whos S1 S2
  Name        Size              Bytes  Class     Attributes

  S1          1x1              120504  struct              
  S2        100x50            1680192  struct              

복소수 배열

MATLAB은 복소수의 실수부/허수부 결합형 저장 표현을 사용합니다. 여기서 실수부와 허수부는 연속 메모리 블록에 함께 저장됩니다. 복소수 배열의 복사본을 만든 다음 배열의 실수부나 허수부만 수정하는 경우, MATLAB은 실수부와 허수부가 모두 포함된 배열을 생성합니다. 메모리에서 복소수 표현에 대한 자세한 내용은 MATLAB Support for Interleaved Complex API in MEX Functions 항목을 참조하십시오.

희소 행렬

0이 아닌 요소의 수가 적은 행렬은 희소 형식을 사용하여 저장하는 것이 좋습니다. 비희소 행렬에서 0이 아닌 요소의 수가 적은 경우 이 행렬을 희소 저장 형식으로 변환하면 일반적으로 메모리 사용량과 코드 실행 시간이 줄어듭니다. sparse 함수를 사용하여 비희소 행렬을 희소 저장 형식으로 변환할 수 있습니다.

예를 들어, 행렬 A를 비희소 형식으로 저장되는 1,000×1,000 크기의 단위 행렬로 지정합니다. A의 희소 형식 복사본으로 B를 만듭니다. 희소 저장 형식에서는 동일한 데이터가 사용하는 메모리의 양이 상당히 적어집니다.

A = eye(1000);
B = sparse(A);
whos A B
  Name         Size                Bytes  Class     Attributes

  A         1000x1000            8000000  double              
  B         1000x1000              24008  double    sparse    

대규모 데이터 세트로 작업하기

대규모 데이터 세트를 사용할 때 배열의 크기를 반복해서 조정하면 프로그램에 메모리 부족 문제가 발생할 수 있습니다. 원래 위치의 사용 가능한 연속 메모리를 초과할 정도로 배열을 확장하는 경우, MATLAB은 배열의 복사본을 만들고 이 복사본을 충분한 공간을 갖는 메모리 블록으로 이동해야 합니다. 이 과정에서 메모리에 원래 배열의 복사본이 두 개 존재하게 됩니다. 이에 따라, 배열에 필요한 메모리 크기가 일시적으로 두 배가 되고, 프로그램이 사용할 수 있는 메모리가 부족할 수 있는 위험이 높아집니다. 이런 경우, 배열에 필요한 최대 공간을 사전할당하여 메모리 사용량과 코드 실행 시간을 개선할 수 있습니다. 자세한 내용은 사전할당(Preallocation) 항목을 참조하십시오.

참고 항목

|

관련 항목