OS Paging Row Column

행 우선 방식(Row-major Order) vs. 열 우선 방식(Column-major Order)

2차원 배열은 메모리에 1차원적으로 저장되므로, 특정한 규칙을 따라야 합니다.
이때, 배열을 메모리에 저장하는 방식에는 **행 우선 방식(Row-major Order)**과 **열 우선 방식(Column-major Order)**이 있습니다.


1. 행 우선 방식(Row-major Order)

행 우선 방식은 행을 기준으로 데이터를 연속적으로 저장하는 방식입니다.
즉, 같은 행의 원소들이 연속적으로 메모리에 저장된 후 다음 행으로 넘어갑니다.

예제

배열 A[3][4] (3행 4열)가 주어졌을 때,
다음과 같이 메모리에 저장됩니다.

배열 구조

A[0][0]A[0][1]A[0][2]A[0][3]
A[1][0]A[1][1]A[1][2]A[1][3]
A[2][0]A[2][1]A[2][2]A[2][3]

메모리 배치 (행 우선)

메모리에 저장되는 순서:

A[0][0], A[0][1], A[0][2], A[0][3], 
A[1][0], A[1][1], A[1][2], A[1][3], 
A[2][0], A[2][1], A[2][2], A[2][3]

메모리 주소 공식 (행 우선)

주소=Base Address+(행 인덱스×열 개수+열 인덱스)×데이터 크기\text{주소} = \text{Base Address} + (\text{행 인덱스} × \text{열 개수} + \text{열 인덱스}) × \text{데이터 크기}

Base Address: 배열의 시작 주소
행 인덱스(Row Index): 찾고자 하는 원소의 행 번호
열 인덱스(Column Index): 찾고자 하는 원소의 열 번호
열 개수(Columns): 한 행에 있는 원소의 개수
데이터 크기: 한 원소의 바이트 크기


예제 1: 행 우선 방식에서 A[2][3]의 메모리 주소 구하기

가정

  • Base Address = 1000
  • 데이터 크기 = 4바이트
  • 배열 크기 = A[3][4]

계산 주소=1000+(2×4+3)×4\text{주소} = 1000 + (2 × 4 + 3) × 4 =1000+(8+3)×4= 1000 + (8 + 3) × 4 =1000+44=1044= 1000 + 44 = 1044

💡 정답: A[2][3]의 주소는 1044


2. 열 우선 방식(Column-major Order)

열 우선 방식은 열을 기준으로 데이터를 연속적으로 저장하는 방식입니다.
즉, 같은 열의 원소들이 연속적으로 메모리에 저장된 후 다음 열로 넘어갑니다.

예제

배열 A[3][4] (3행 4열)가 주어졌을 때,
다음과 같이 메모리에 저장됩니다.

배열 구조

A[0][0]A[0][1]A[0][2]A[0][3]
A[1][0]A[1][1]A[1][2]A[1][3]
A[2][0]A[2][1]A[2][2]A[2][3]

메모리 배치 (열 우선)

메모리에 저장되는 순서:

A[0][0], A[1][0], A[2][0], 
A[0][1], A[1][1], A[2][1], 
A[0][2], A[1][2], A[2][2], 
A[0][3], A[1][3], A[2][3]

메모리 주소 공식 (열 우선)

주소=Base Address+(열 인덱스×행 개수+행 인덱스)×데이터 크기\text{주소} = \text{Base Address} + (\text{열 인덱스} × \text{행 개수} + \text{행 인덱스}) × \text{데이터 크기}

Base Address: 배열의 시작 주소
열 인덱스(Column Index): 찾고자 하는 원소의 열 번호
행 인덱스(Row Index): 찾고자 하는 원소의 행 번호
행 개수(Rows): 한 열에 있는 원소의 개수
데이터 크기: 한 원소의 바이트 크기


예제 2: 열 우선 방식에서 A[2][3]의 메모리 주소 구하기

가정

  • Base Address = 1000
  • 데이터 크기 = 4바이트
  • 배열 크기 = A[3][4]

계산 주소=1000+(3×3+2)×4\text{주소} = 1000 + (3 × 3 + 2) × 4 =1000+(9+2)×4= 1000 + (9 + 2) × 4 =1000+44=1044= 1000 + 44 = 1044

💡 정답: A[2][3]의 주소는 1044


3. 행 우선 vs. 열 우선의 차이점

구분행 우선(Row-major)열 우선(Column-major)
저장 방식행을 기준으로 연속 저장열을 기준으로 연속 저장
주소 공식Base + (Row * Columns + Col) * DataSizeBase + (Col * Rows + Row) * DataSize
사용 언어C, C++, Java 등Fortran, MATLAB 등
캐시 효율성2D 배열을 순차적으로 접근할 때 더 효율적특정 열을 연속적으로 접근할 때 더 효율적

4. 캐시 효율성 차이

행 우선 방식이 유리한 경우

  • 대부분의 프로그래밍 언어(C, C++, Java 등)가 행 우선 방식을 사용합니다.
  • for 문을 사용할 때, 행 단위로 순차적으로 접근하면 캐시 적중률(Cache Hit)이 높아 성능이 향상됩니다.
// 행 우선 방식 (더 빠름)
for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
        sum += A[i][j];  // 메모리 캐시 친화적
    }
}

열 우선 방식이 불리한 경우

  • 행 우선 방식에서 열을 순회하면 캐시 미스(Cache Miss)가 자주 발생합니다.
// 열 우선 방식 (더 느림)
for (int j = 0; j < cols; j++) {
    for (int i = 0; i < rows; i++) {
        sum += A[i][j];  // 캐시 미스 증가
    }
}

결론

  1. C, C++, Java는 행 우선 방식(Row-major Order)을 사용하며, 일반적으로 더 효율적입니다.
  2. Fortran, MATLAB은 열 우선 방식(Column-major Order)을 사용합니다.
  3. 캐시 효율성을 고려하면 행 우선 방식이 대부분의 경우 더 빠릅니다.

궁금한 점 있으면 질문 주세요! 😊

Leave a Reply

Your email address will not be published. Required fields are marked *