가장 왼쪽에있는 인덱스가 가장 빠르게 변하는 것이 더 효율적인 이유를 설명하는 다소 긴 답변. 이해해야 할 두 가지 중요한 사항이 있습니다.
먼저, MATLAB (및 C 및 대부분의 다른 프로그래밍 언어가 아닌 포트란)은 배열을 "열 주요 순서"로 메모리에 저장합니다. 예를 들어 A가 2 x 3 x 10 행렬이면 항목은 순서대로 메모리에 저장됩니다.
A (1,1,1)
A (2,1,1)
A (1,2,1)
A (2,2,1)
A (1,3,1)
A (2,3,1)
A (1,1,2)
A (2,1,2)
...
A (2,3,10)
이 컬럼 메이저 순서의 선택은 임의적입니다. 우리는 "행 메이저 순서"규칙을 쉽게 채택 할 수있었습니다. 실제로 C와 다른 프로그래밍 언어에서 수행됩니다.
두 번째로 알아야 할 중요한 점은 최신 프로세서는 한 번에 한 위치에 메모리에 액세스하지 않고 64 또는 128 연속 바이트 (8 또는 16 배정 밀도 부동 소수점 숫자)의 "캐시 라인"을로드하고 저장한다는 것입니다. 메모리에서 한 번에. 이러한 데이터 청크는 빠른 메모리 캐시에 임시 저장되고 필요에 따라 다시 쓰여집니다. (실제로 캐시 아키텍처는 3 ~ 4 레벨의 캐시 메모리로 상당히 복잡하지만 기본 아이디어는 컴퓨터가 어린 시절에 있었던 일종의 1 레벨 캐시로 설명 할 수 있습니다.)
A
가장 안쪽의 루프가 행 첨자를 업데이트하도록 루프가 중첩 된 경우 배열 항목은 순서대로 A (1,1), A (2,1), A (3,1), ... 첫 번째 항목 A (1,1)에 액세스하면 시스템은 A (1,1), A (2,1), ..., A (8,1)을 포함하는 캐시 라인을 주 메모리에서 캐시로 가져옵니다. . 가장 안쪽 루프의 다음 8 번 반복은 추가 주 메모리 전송없이이 데이터에서 작동합니다.
대안으로, 열 인덱스가 가장 안쪽 루프에서 변하도록 루프를 구성하면 A의 항목은 A (1,1), A (1,2), A (1,3 순서로 액세스됩니다. ), ...이 경우 첫 번째 액세스는 A (1,1), A (2,1), ..., A (8,1)을 주 메모리에서 캐시로 가져 오지만 이러한 항목은 사용되지 않습니다. 두 번째 반복에서 A (1,2)에 대한 액세스는 주 메모리에서 다른 8 개의 항목을 가져옵니다. 코드가 행렬의 행 2에서 작동 할 때까지 A (2,1) 항목이 캐시에서 플러시되어 다른 필요한 데이터를 처리 할 수 있습니다. 결과적으로 코드는 필요한 트래픽의 8 배를 생성합니다.
일부 최적화 컴파일러는이 문제를 피하기 위해 루프를 자동으로 재구성 할 수 있습니다.
행렬 곱셈 및 인수 분해를위한 많은 수치 선형 대수 알고리즘은 프로그래밍 언어에 따라 행 주요 또는 열 주요 순서 체계와 효율적으로 작동하도록 최적화 될 수 있습니다. 이를 잘못된 방식으로 수행하면 성능에 상당한 부정적인 영향을 줄 수 있습니다.
For
MATLAB에서는 루프가 매우 느립니다. 가능하면 MATLAB에서 명시적인 루프를 피해야합니다. 대신, 보통 문제는 행렬 / 벡터 연산으로 표현 될 수 있습니다. 이것이 MATLABic 방식입니다. 행렬 등을 초기화하는 내장 함수도 많이 있습니다. 예를 들어, 행렬의 모든 요소를 1 (확장, 곱셈 (스칼라)로 설정하는 ones () 함수가 있습니다. all-ones 행렬을 곱한 값)). 3D 배열에서도 작동합니다 (여기서는 예제를 다루는 것으로 생각됩니다).