밀집 행렬 계산을 프로그래밍 할 때 열-주요 레이아웃에서 행-주요 레이아웃을 선택해야하는 이유가 있습니까?
선택한 매트릭스의 레이아웃에 따라 캐시 메모리를 속도 목적으로 효과적으로 사용하려면 적절한 코드를 작성해야합니다.
행-주요 레이아웃은 더 자연스럽고 단순 해 보입니다 (적어도 나에게는). 그러나 Fortran으로 작성된 LAPACK과 같은 주요 라이브러리는 열 주요 레이아웃을 사용하므로이 선택을 한 이유가 있어야합니다.
밀집 행렬 계산을 프로그래밍 할 때 열-주요 레이아웃에서 행-주요 레이아웃을 선택해야하는 이유가 있습니까?
선택한 매트릭스의 레이아웃에 따라 캐시 메모리를 속도 목적으로 효과적으로 사용하려면 적절한 코드를 작성해야합니다.
행-주요 레이아웃은 더 자연스럽고 단순 해 보입니다 (적어도 나에게는). 그러나 Fortran으로 작성된 LAPACK과 같은 주요 라이브러리는 열 주요 레이아웃을 사용하므로이 선택을 한 이유가 있어야합니다.
답변:
기존 소프트웨어를 고려하지 않고 진공 상태에서 코드 관점에서 행 전공보다 열 전공을 선호하는 이유는 없습니다. 그러나 대부분의 수학 문헌은 벡터를 행 대신 열로 저장하여 벡터를 행렬로 그룹화하는 방식으로 작성되었습니다. 예를 들어, 당신은 전체 고유치 방정식 쓸 때 는 X행렬에는 열로 작성된 모든 고유 벡터가 포함됩니다. 당신은 실제로 다른 방법으로 작성된 것을 보지 못합니다 (행 통계와 같은 사람들은 행 벡터와 같은 것을 들었습니다). 따라서 초기 소프트웨어에서 열 주요 형식을 사용하는 것이 당연했습니다. 따라서 벡터 집합 인 행렬이있는 경우 단일 벡터의 저장이 연속적입니다. 따라서, 나는 전통이 현재까지 이어져 왔다고 생각합니다. 그리고 예전의 포트란과 대화하고 싶다면, 컬럼 메이저를 사용하고 싶습니다. 따라서 대부분의 매우 효율적인 수치 선형 대수학은 주요 열에서 수행됩니다.
C가 행 메이저 인 이유는 배열 구문의 결과입니다. 3 행 x 2 열 배열을로 선언하면 double a[3][2]
나중에 인덱스가 이전 인덱스보다 빠르게 변하므로 2D 배열의 경우 행을 주요하게 만듭니다. 이것을 왼쪽에서 오른쪽으로 자연 서양의 읽기 순서와 결합하면 행 전공이 더 자연스럽게 보입니다.
열 주요 순서가 더 자연스러운 것 같습니다. 예를 들어 영화를 그림별로 파일로 저장하려면 열 순서를 사용하고 있으며 매우 직관적이며 아무도 행 주요 순서로 저장하지 않는다고 가정하십시오.
C / C ++에서 프로그래머라면 기본 열 주요 순서와 함께 매트릭스 (Eigen, Armadillo 등)에 대해 상위 레벨 라이브러리를 사용해야합니다. C / C ++는 행렬 인덱싱을 상기시키는 무언가를 제공하지만 열악한 순서로 원시 C 포인터를 미치광이 만 사용합니다.
간결성을 위해 행 전공 순서가있는 모든 항목은 최소한 이상하게 구성된 것으로 간주해야합니다. 슬라이스 별 슬라이스는 단순히 자연적인 순서이며 포트란과 같은 열 주요 순서를 의미합니다. 우리 아버지 / 어머니는 왜 그것을 선택했는지 아주 좋은 이유가있었습니다.
불행히도 몇 가지 흥미로운 라이브러리는 경험이 부족하기 때문에 행 순서로 만들어졌습니다.
오른쪽 인덱스가 메모리를 통해 한 단계에서 더 빨리 변하는 행 주요 순서의 정의를 명확히하기 위해 : A (x, y, z) 그것은 z 인덱스입니다. 즉, 다른 슬라이스의 메모리 픽셀에서 인접한다는 것을 의미합니다. 원하지 않아요 영화 A (x, y, t)의 경우 마지막 색인은 시간 t입니다. 영화를 행 전공 모드로 저장하는 것이 불가능하다는 것은 상상하기 어렵지 않습니다.
이제 다음 알고리즘을 상상해보십시오.
for i from 1 to m
for j from 1 to n
do something with m(i,j)
행 주요 순서를 사용하면 모든 선형 인덱스 통과합니다.순차적으로, 메모리 로컬 성이 양호하지만, 열-주요 순서가 사용되는 경우 연속 메모리 액세스는 메모리에 흩어집니다. 가상 메모리 / 스와핑이 장면에 들어갈 때 특히 결과가 극적으로 나타날 수 있습니다.
결론 :
예, 중요하지만 선택은 데이터가 액세스되는 방식에 따라 다릅니다. 이전 예에서 열 순서를 사용하는 경우 간단히 두 루프를 교체하면됩니다.
일반적으로 빠르게 변하는 인덱스는 메모리의 연속 위치에 매핑되어야합니다.
더 중요한 것은 선택의 영향을 측정 / 벤치마킹 하는 것이 기본입니다. 많은 매개 변수 (데이터 크기, 캐시 크기, 사용 된 언어가 여러 인덱스를 선형 인덱스에 매핑하는 방식, 운영 방식에 따라 달라지기 때문입니다) 시스템은 가상 메모리를 관리합니다. 루프가 사용하는 선형 대수 라이브러리에 중첩되는 방식 ...)