Main Content

이 페이지의 최신 내용은 아직 번역되지 않았습니다. 최신 내용은 영문으로 볼 수 있습니다.

효율적인 메모리 사용을 위한 전략

여기에서는 MATLAB®에서 메모리를 효율적으로 사용할 수 있는 몇 가지 방법에 대해 설명합니다.

적절한 데이터 저장소 사용하기

MATLAB에서는 double형, uint8형 등, 다양한 크기의 데이터 클래스를 제공합니다. 따라서 비교적 작은 데이터 세그먼트를 저장하는 데 크기가 큰 클래스를 사용할 필요가 없습니다. 예를 들어, 부호 없는 작은 정수 값 1,000개를 저장할 때 uint8형 클래스를 사용하면 double형 클래스를 사용할 때에 비해 7KB 더 적은 메모리를 차지합니다.

적절한 숫자형 클래스 사용하기

MATLAB에서 사용해야 할 숫자형 클래스는 의도하는 동작에 따라 달라집니다. 디폴트 double형 클래스를 사용하면 정밀도가 가장 높지만 요소당 8바이트의 메모리가 필요합니다. 선형 대수와 같은 복잡한 수학 연산을 수행하려는 경우 double형이나 single형과 같은 부동소수점 클래스를 사용해야 합니다. single형 클래스에는 4바이트만 필요합니다. single형 클래스로 수행할 수 있는 연산에는 몇 가지 제한 사항이 있지만, 대부분의 MATLAB 수학 연산이 지원됩니다.

단순 산술만 수행해야 하며 원래 데이터를 정수로 나타내는 경우 MATLAB의 정수형 클래스를 사용할 수 있습니다. 다음은 숫자형 클래스, 메모리 요구 사항(단위: 바이트), 지원되는 연산의 목록입니다.

클래스(데이터형)바이트지원되는 연산
single4대부분의 수학 연산
double8모든 수학 연산
logical1논리/조건 연산
int8, uint81산술 연산과 일부 간단한 함수
int16, uint162산술 연산과 일부 간단한 함수
int32, uint324산술 연산과 일부 간단한 함수
int64, int648산술 연산과 일부 간단한 함수

데이터 저장 시 오버헤드 줄이기

MATLAB 배열(내부적으로 mxArrays로 구현됨)은 유형, 차원, 특성(Attribute)과 같은 데이터에 대한 메타 정보를 저장할 공간이 메모리에 필요합니다. 배열당 약 104바이트가 사용됩니다. 이 오버헤드는 작은 mxArrays(예: 스칼라)가 대량(예: 수백 개 또는 수천 개)으로 있는 경우에만 문제가 됩니다. whos 명령은 변수가 사용하는 메모리를 나열하지만 이 오버헤드는 포함하지 않습니다.

하나의 mxArray로 구성된 간단한 숫자형 배열의 경우 오버헤드가 가장 적기 때문에, 가능한 경우 항상 이 배열을 사용해야 합니다. 데이터가 복잡해서 단순 배열(또는 행렬)에 저장할 수 없을 때는 다른 데이터 구조를 사용할 수 있습니다.

셀형 배열은 각 요소에 대한 별도의 mxArrays로 구성됩니다. 따라서 작은 요소 여러 개가 있는 셀형 배열의 경우 오버헤드가 커집니다.

구조체에는 필드당 비슷한 양의 오버헤드가 필요합니다(배열 헤더 항목 참조). 필드가 많으면서 그 내용이 작은 구조체는 큰 오버헤드를 가지므로 피해야 합니다. 숫자형 스칼라 필드가 있는 큰 구조체 배열은 큰 숫자형 배열이 포함된 필드를 가진 구조체보다 훨씬 더 많은 메모리를 필요로 합니다.

참고로, MATLAB은 숫자형 배열을 연속 메모리에 저장하지만 구조체나 셀형 배열의 경우에는 그렇지 않습니다.

적절한 MATLAB 클래스로 데이터 가져오기

fread를 사용하여 이진 파일에서 데이터를 읽어 들일 때, 파일에 있는 데이터의 클래스만 지정하고, 데이터가 작업 공간에 있을 때 MATLAB에서 사용하는 데이터의 클래스는 지정하지 않는 오류를 사용자들이 흔히 범하곤 합니다. 그 결과, 8비트 값만 읽어 들이더라도 디폴트 double형이 사용됩니다. 예를 들면 다음과 같습니다.

fid = fopen('large_file_of_uint8s.bin', 'r'); 
a = fread(fid, 1e3, 'uint8');              % Requires 8k 
whos a
  Name         Size            Bytes  Class    Attributes
 
  a         1000x1              8000  double    
  
a = fread(fid, 1e3, 'uint8=>uint8');       % Requires 1k 
whos a
  Name         Size            Bytes  Class    Attributes
 
  a         1000x1              1000  uint8

가능한 경우 희소 배열 만들기

데이터에 0이 많이 포함된 경우 0이 아닌 요소만 저장하는 희소 배열을 사용하는 것이 좋습니다. 다음 예제에서는 희소 저장과 비희소 저장의 요구 사항을 비교합니다.

A = eye(1000);        % Full matrix with ones on the diagonal
As = sparse(A);       % Sparse matrix with only nonzero elements
whos
  Name         Size                Bytes  Class     Attributes

  A         1000x1000            8000000  double              
  As        1000x1000              24008  double    sparse  

이 배열을 희소 배열로 저장하려면 약 4KB만 있으면 되지만 비희소 행렬로 저장하려면 약 8MB가 필요한 것을 확인할 수 있습니다. 일반적으로, nnz(0이 아님) 요소와 ncol 열이 있는 double형 희소 배열의 경우 필요한 메모리는 다음과 같습니다.

  • 16 * nnz + 8 * ncol + 8바이트(64비트 컴퓨터의 경우)

MATLAB은 희소 배열에서 전부는 아니지만 대부분의 수학 연산을 지원합니다.

임시 데이터 복사본 방지하기

불필요한 임시 데이터 복사본 생성을 방지하여 필요한 메모리 양을 상당히 줄일 수 있습니다.

임시 배열 생성 지양하기

대용량 임시 변수를 만들지 말고, 임시 변수가 더 이상 필요하지 않을 때는 항상 이 변수를 지우는 것이 좋습니다. 예를 들어, 다음 코드는 임시 변수 A로 저장되는, 0으로 구성된 배열을 만든 후 A를 단정밀도로 변환합니다.

A = zeros(1e6,1);
As = single(A);

다음과 같이 하나의 명령을 사용하여 두 작업을 모두 수행하는 것이 메모리 효율이 더 높습니다.

A = zeros(1e6,1,'single');

repmat 함수를 사용하는 경우, 배열 사전할당(Preallocation)과 for 루프를 통해 메모리의 임시 저장 공간 없이도 비double형 데이터에 대한 작업을 수행할 수 있습니다.

중첩 함수를 사용하여 전달할 인수 개수 줄이기

대규모 데이터 세트를 가지고 작업할 때, 호출된 함수가 입력 변수의 값을 수정하는 경우 MATLAB이 이 입력 변수의 임시 복사본을 만든다는 것에 주의하십시오. 이때 배열을 저장하는 데 필요한 메모리가 일시적으로 배로 늘어나며, 이로 인해 충분한 메모리를 사용할 수 없는 경우 MATLAB에서 오류가 발생합니다.

이 상황에서 메모리 사용량을 줄이는 방법은 중첩 함수를 사용하는 것입니다. 중첩 함수는 모든 바깥쪽 함수의 작업 공간을 공유하여, 중첩 함수가 일상 범위 밖에 있는 데이터에 액세스할 수 있게 됩니다. 여기에 나온 예제에서는 중첩 함수 setrowval이 바깥쪽 함수 myfun의 작업 공간에 직접 액세스할 수 있어, 함수 호출에서 변수의 복사본을 전달할 필요가 없습니다. setrowvalA의 값을 수정하면 호출하는 함수의 작업 공간에서 이 값이 수정됩니다. 호출되는 함수에 대한 별도의 배열을 수용하기 위해 추가 메모리를 사용할 필요가 없으며, 수정된 A 값을 반환할 필요도 없습니다.

function myfun
A = magic(500);

   function setrowval(row, value)
   A(row,:) = value;
   end

setrowval(400, 0);
disp('The new value of A(399:401,1:10) is')
A(399:401,1:10)
end

사용한 메모리 반환 받기

사용 가능한 메모리 양을 늘릴 수 있는 한 가지 간단한 방법은 더 이상 사용하지 않는 큰 배열을 지우는 것입니다.

주기적으로 대용량의 데이터를 디스크에 저장하기

프로그램이 아주 큰 용량의 데이터를 생성하는 경우 데이터를 주기적으로 디스크에 쓰는 것이 좋습니다. 데이터의 해당 부분을 저장한 후에는 clear 함수를 사용하여 메모리에서 변수를 제거하고 데이터 생성을 계속합니다.

메모리에서 더 이상 필요 없는 오래된 변수 지우기

매우 큰 대규모 데이터 세트를 반복적으로 또는 대화형 방식으로 작업할 때는 먼저 오래된 변수를 지워 새 변수를 위한 공간을 만들도록 하십시오. 그러지 않으면, MATLAB은 변수를 재정의(Override)하기 전에 같은 크기의 임시 저장 공간을 필요로 합니다. 예를 들면 다음과 같습니다.

a = rand(1e5);
b = rand(1e5);
Out of memory.

More information
 
 
clear a
a = rand(1e5);              % New array 

관련 항목