28.17 스트라이드(Stride)의 정의와 텐서 원소 접근의 메모리 주소 계산

28.17 스트라이드(Stride)의 정의와 텐서 원소 접근의 메모리 주소 계산

스트라이드는 텐서의 각 축(axis)을 따라 인접한 원소 사이에 존재하는 메모리 상의 간격을 수치화한 개념이다. 스트라이드 기반의 원소 접근 체계는 행 우선 또는 열 우선의 단순 레이아웃을 일반화함으로써, 물리적 데이터 복사 없이도 전치(transpose), 슬라이싱(slicing), 차원 치환(permutation), 확장(broadcasting) 등의 다양한 뷰 연산을 효율적으로 구현할 수 있게 한다. 현대 딥러닝 프레임워크의 텐서 자료 구조는 모두 스트라이드 개념을 중심으로 설계되어 있다.

1. 스트라이드의 정의

형상이 (d_1, d_2, \ldots, d_n)n차 텐서 T의 스트라이드는 각 축 k에 대하여, 해당 축의 지표 i_k가 1만큼 증가했을 때 메모리 주소가 증가해야 하는 원소 수로 정의된다. 이를 벡터 형태로 \mathbf{s} = (s_1, s_2, \ldots, s_n)으로 표기한다. 스트라이드를 이용한 원소의 선형 오프셋은 다음과 같이 계산된다.

f(i_1, i_2, \ldots, i_n) = \sum_{k=1}^{n} i_k \cdot s_k

그리고 실제 메모리 주소는 다음과 같이 주어진다.

\mathrm{addr}(i_1, \ldots, i_n) = b_0 + \text{itemsize} \cdot \sum_{k=1}^{n} i_k \cdot s_k

여기서 b_0는 텐서의 기준 주소, \text{itemsize}는 개별 원소의 바이트 크기이다. 프레임워크에 따라 스트라이드 단위가 원소 수로 정의되기도 하고(PyTorch) 바이트 수로 정의되기도 한다(NumPy).

2. 연속(contiguous) 레이아웃의 표준 스트라이드

텐서가 연속적인 행 우선 레이아웃을 가질 때, 표준 스트라이드는 다음과 같이 계산된다.

s_k^{\text{row}} = \prod_{j=k+1}^{n} d_j, \qquad s_n^{\text{row}} = 1

예를 들어 형상 (3, 4, 5)의 3차 텐서에서 행 우선 스트라이드는 \mathbf{s} = (20, 5, 1)이다. 열 우선 레이아웃의 표준 스트라이드는 다음과 같다.

s_k^{\text{col}} = \prod_{j=1}^{k-1} d_j, \qquad s_1^{\text{col}} = 1

동일한 (3, 4, 5) 텐서의 열 우선 스트라이드는 \mathbf{s} = (1, 3, 12)가 된다.

3. 데이터 복사 없는 뷰(View) 연산

스트라이드 체계의 핵심 이점은 원본 데이터를 복사하지 않고도 새로운 텐서 해석을 생성할 수 있다는 점이다. 아래 표는 대표적인 뷰 연산에서 형상과 스트라이드의 변화를 요약한다.

연산입력 형상입력 스트라이드출력 형상출력 스트라이드
전치 (2차)(M, N)(N, 1)(N, M)(1, N)
축 치환(d_1, d_2, d_3)(s_1, s_2, s_3)(d_{\pi(1)}, d_{\pi(2)}, d_{\pi(3)})(s_{\pi(1)}, s_{\pi(2)}, s_{\pi(3)})
슬라이싱(d_1, d_2)(s_1, s_2)슬라이스 길이간격 \times 원 스트라이드
확장(broadcast)(1, N)(N, 1)(M, N)(0, 1)

특히 브로드캐스팅은 스트라이드를 0으로 설정하는 기법을 통해, 실제 메모리 확장 없이 가상적으로 축을 반복하는 효과를 얻는다.

4. 메모리 연속성과 성능

스트라이드 표현으로 기술되는 임의의 텐서가 항상 연속적인(contiguous) 메모리 접근을 보장하는 것은 아니다. 전치 또는 불규칙한 슬라이싱을 수행한 텐서는 비연속(non-contiguous) 상태가 되며, 이는 캐시 효율 저하와 일부 최적화된 커널의 사용 불가로 이어질 수 있다. 행 우선 연속성 여부는 다음 조건으로 검사할 수 있다.

s_n = 1 \quad \text{이고} \quad s_k = s_{k+1} \cdot d_{k+1},\ \forall k = 1, \ldots, n-1

이 조건이 만족되지 않는 텐서에 대해 프레임워크는 필요 시 contiguous() 연산을 통해 데이터를 재복사하여 표준 스트라이드로 재구성한다.

5. 계산 예시

형상 (3, 4)이고 행 우선 레이아웃을 갖는 행렬 T를 가정하자. 표준 스트라이드는 \mathbf{s} = (4, 1)이고, 원소 T[2, 3]의 오프셋은 2 \cdot 4 + 3 \cdot 1 = 11이다. 이 행렬을 전치한 T^\top의 형상은 (4, 3)이지만, 기저 데이터는 동일하며 스트라이드만 (1, 4)로 변경된다. 전치된 텐서에서 T^\top[3, 2]의 오프셋은 3 \cdot 1 + 2 \cdot 4 = 11로, 원본 T[2, 3]과 정확히 동일한 물리적 위치를 가리킨다. 이 예시는 스트라이드 체계가 어떻게 데이터 복사 없이 동일한 원소를 여러 논리적 형태로 참조할 수 있게 하는지를 명확히 보여준다. 스트라이드 기반 주소 계산은 텐서 라이브러리의 성능과 메모리 효율을 결정짓는 가장 근본적인 설계 요소이다.