MATLAB의 메모리 할당 방식
이 항목에서는 변수를 사용할 때 MATLAB®이 메모리를 할당하는 방법에 대한 정보를 제공합니다. MATLAB이 내부적으로 데이터를 처리하는 방법 등과 같은 이러한 정보는 향후 릴리스에서 변경될 수 있습니다.
배열의 메모리 할당
숫자형 배열이나 문자형 배열을 변수에 대입하면 MATLAB은 연속 메모리 블록을 할당하고 이 블록에 배열 데이터를 저장합니다. MATLAB은 또한 배열의 클래스와 차원 등, 배열 데이터에 대한 정보를 헤더라는 별도의 작은 메모리 블록에 저장합니다. 대부분의 배열에서 헤더를 저장하는 데 필요한 메모리는 미미한 정도입니다. 하지만 대규모 데이터 세트를 많은 수의 작은 배열 대신 적은 수의 큰 배열에 저장하면 몇 가지 이점이 있을 수 있습니다. 배열 수가 적을수록 필요한 배열 헤더도 적어지기 때문입니다.
기존 배열에 새 요소를 추가하는 경우, MATLAB은 저장소가 연속되도록 유지하는 방식으로 메모리의 배열을 확장합니다. 일반적으로 이렇게 하려면 확장된 배열을 수용할 만큼 크기가 충분한 새 메모리 블록을 찾아야 합니다. 그러면 MATLAB은 원래 위치에서 이 새 메모리 블록으로 배열의 내용을 복사하고, 이 블록의 배열에 새 요소를 추가하고, 원래 배열이 있던 위치의 메모리를 해제합니다.
기존 배열에서 요소를 제거하는 경우, MATLAB은 삭제된 요소를 제거한 후 원래 메모리 위치에서 해당 저장소를 축약하여 메모리 저장소가 연속되도록 유지합니다.
배열 복사하기
배열을 두 번째 변수에 대입하면(예를 들어, B = A
를 실행하는 경우) MATLAB은 새 메모리를 즉시 할당하지 않습니다. 대신, 배열 참조의 복사본을 만듭니다. A
및 B
에서 참조하는 메모리 블록의 내용을 수정하지 않는 한, 두 개 이상의 데이터 복사본을 저장할 필요가 없습니다. 하지만, A
또는 B
를 사용하여 메모리 블록의 요소를 수정하면 MATLAB이 새 메모리를 할당하고 데이터를 이 메모리로 복사한 후 생성된 복사본을 수정합니다.
함수 인수
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비트 시스템에서 S1
과 S2
에 할당된 메모리의 양을 비교합니다. S1
과 S2
에 동일한 데이터가 포함되어 있지만, S1
은 현저히 작은 메모리를 사용합니다.
whos S1 S2
Name Size Bytes Class Attributes S1 1x1 120403 struct S2 100x50 1920043 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) 항목을 참조하십시오.