matlab-사전할당(Preallocation)

정세형·2023년 7월 10일

matlab

목록 보기
3/3

서론

MATLAB에서 FOR loop를 돌리기 전, 만약 행렬의 사이즈를 미리 정의하지 않는다면 메모리 조각화 문제가 발생할 수 있음

for i=1:10
      x(i)=i;
end

FOR loop가 실행되면 MATLAB은 i=1을 확인하고 운영 체제에 1 x 1 행렬을 생성하기에 충분한 메모리를 요청하고 x(1)=1을 생성. i=2인 경우 MATLAB은 1 x 2 행렬을 저장할 수 있도록 더 많은 메모리를 요청함.
이 추가 메모리가 x(1)=1일 때와 동일한 연속 메모리 스트립(strip)에 있는 경우 MATLAB은 단순히 동일한 메모리 스트립에 추가함.

원래 메모리 스트립이 1x1 행렬만 들어갈수 있고 1x2행렬은 안들어가는 경우, MATLAB은 x(1)=1 값을 1x2 행렬도 넣을만큼 충분히 큰 메모리 지점으로 옮김. 이제 행렬이 1x2이므로 원래 메모리 슬롯은 1x1보다 큰 행렬에 대해 쓸모가 없어짐. 이 메모리는 이제 단편화되어 FOR 루프에서 문제를 일으킬 수 있음.

이 문제를 해결하려면 FOR 루프에서 행렬의 최종 크기로 0의 초기 행렬을 만들어 메모리를 미리 할당해야함.

  • 예를 들어 a = zeros(1000)을 입력하면 크기가 1000x1000인 행렬 'a'에 대해 메모리에 충분한 연속 공간을 할당받을 수 있음.
    이렇게 하면 'a'가 이를 보유하고 있는 블록보다 커질 때마다 메모리에서 연속적인 여유 공간의 새 블록을 찾는 대신 MATLAB은 이제 행렬 'a'에 대해 미리 할당된 메모리 공간의 값만 변경함.

사전할당(Preallocation)

배열 또는 행렬을 미리 크기를 지정하여 생성
해당 크기를 벗어나는 인덱스에 접근하는 것은 불가능함

  • 사전할당은 배열 크기를 미리 알고 있는 경우에 유용
  • 배열 크기가 변하지 않을 때 사용함.
A = zeros(3, 3); // 3x3 크기의 0으로 채워진 배열을 사전할당하여 생성

숫자형 배열이나 문자형 배열을 변수에 대입하면 MATLAB은 연속 메모리 블록을 할당하고 이 블록에 배열 데이터를 저장

배열 데이터에 대한 정보를 헤더라는 별도의 작은 메모리 블록에 저장

  • 기존 배열에 새 요소를 추가하는 경우,
    MATLAB은 저장소가 연속되도록 유지하는 방식으로 메모리의 배열을 확장함. 일반적으로 이렇게 하려면 확장된 배열을 수용할 만큼 크기가 충분한 새 메모리 블록을 찾아야함. 그러면 MATLAB은 원래 위치에서 이 새 메모리 블록으로 배열의 내용을 복사하고, 이 블록의 배열에 새 요소를 추가하고, 원래 배열이 있던 위치의 메모리를 해제함. (번외 : c언어의 realloc과 유사한 원리)
  • 배열 복사하기
    배열을 두 번째 변수에 대입하면(예를 들어, B = A를 실행하는 경우) MATLAB은 새 메모리를 즉시 할당하지 않음. 대신, 배열 참조의 복사본을 만들고, A 및 B에서 참조하는 메모리 블록의 내용을 수정하지 않는 한, 두 개 이상의 데이터 복사본을 저장할 필요가 없음. 하지만, A 또는 B를 사용하여 메모리 블록의 요소를 수정하면 MATLAB이 새 메모리를 할당하고 데이터를 이 메모리로 복사한 후 생성된 복사본을 수정함.

시간 차이

tic;
for i=1:1000,
      for j=1:1000,
          x(i,j)=i+j;
      end
end
toc

Elapsed time is 12.175349 seconds.

tic;
x=zeros(1000);
for i=1:1000,
      for j=1:1000,
          x(i,j)=i+j;
      end
end
toc

Elapsed time is 1.761482 seconds.

profile
👨‍💻github.com/pos1504 💌pos1504@gmail.com 🙋‍♂️https://www.linkedin.com/in/%EC%84%B8%ED%98%95-%EC%A0%95-68067b287/

0개의 댓글