λ°μν
C++ μμ νλ ¬κ³± μ°μ°μ ꡬνν λ, μ¬λ¬ λ°©λ²μ λ°λΌ μλ μ°¨μ΄κ° λ§μ΄ λλ€κ³ ν΄μ κ°λ¨ν μ€νμΌλ‘ μλ λΉκ΅λ₯Ό ν΄λ³΄μμ΅λλ€. νλ ¬κ³± μ°μ° κ³Όμ μ λ°λ‘ μ€λͺ νμ§ μκ³ , κ°μ₯ λμ΄λΈν λ°©μμμ μλλ₯Ό ν₯μμν¬ μ μλ λͺκ°μ§ λ°©λ²λ€μ λ¨κ³μ μΌλ‘ μ€λͺ ν©λλ€.
μ¬μ€ νλ ¬ μ°μ° μ λ§μ΄ μ¬μ©νλ Eigen λΌμ΄λΈλ¬λ¦¬λ₯Ό μ°λ©΄ μ΅μ νκ° μλμ΄ μμ΄μ μ€λ¬΄μμ νλ ¬ μ°μ°μ μ§μ ꡬνν΄μΌν μν©μ΄ μΌλ§λ μλμ§λ μ λͺ¨λ₯΄κ² μ΅λλ€. μμ§ κ²½νμ΄ λ§μ΄ μμ΄μ... γ
Baseline (naive version)
/*
@input
mat_x: m x k size matrix
mat_y: k x n size matrix
@output
mat_z: m x n size matrix
*/
void matmult_baseline(int M, int N, int K, const float* mat_x, const float* mat_y, float* mat_z)
{
for (int i = 0; i < M; i++)
for (int j = 0; j < N; j++)
for (int k = 0; k < K; k++)
mat_z[N * i + j] += mat_x[i * K + k] * mat_y[k * N + j];
}
κΈ°λ³Έμ μΈ νλ ¬κ³± μ°μ°μ Aνλ ¬μ rowμ B νλ ¬μ columnμ κ° μμλΌλ¦¬ κ³±νκ³ λνλ κ³Όμ μΌλ‘ ꡬμ±λ©λλ€.
μ¦, μ΄ μΈκ°μ index(e.g. i,j,k)κ° νμνμ¬ μΌμ€ forλ¬Έμ μννλ©° κ³μ°νλ―λ‘ μκ° λ³΅μ‘λ (O^3) λ₯Ό κ°μ§λ―λ‘ κΈ°λ³Έμ μΌλ‘ μ°μ°μ΄ λΉ λ₯΄μ§λ μκ² κ΅¬λ μκ°μ΄ λλλ€.
μ΄ λ, μ μ₯λ νλ ¬μ μμλ₯Ό νμ λ°κΏκ°λ©° νΈμΆνκ² λλλ° μ΄λ cache λ©λͺ¨λ¦¬λ₯Ό κ΅μ₯ν λΉν¨μ¨μ μΌλ‘ μ¬μ©νλ λ°©λ²μ΄κΈ°μ μκ°μ΄ μ€λ κ±Έλ¦¬κ² λ©λλ€.
Cache λ©λͺ¨λ¦¬λ μ¬μ΄μ¦κ° μκ³ μ ννλ©° μ§κΈ μ¬μ©νλ μ£Όμκ° κ·Όμ²μ κ°μ μ κ·Όνλ κ²½μ°μλ ν¨μ¨μ μΌλ‘ μ¬μ©μ΄ κ°λ₯νμ§λ§, λ©λ¦¬μλ μ£Όμκ°μ λ°λ³΅μ μΌλ‘ μ κ·Ό μ ν¨μ¨μ΄ λ¨μ΄μ Έ μκ°μ΄ μ€λ κ±Έλ¦¬κ² λ©λλ€.
μ¦, νλ ¬ κ³± μ°μ°μ rowλ₯Ό μμ§μ΄λ©΄μ μμμ μ κ·Όνλ©΄ νλ ¬ μ¬μ΄μ¦κ° ν° κ²½μ°μλ coulmn size * sizeof(~) λ§νΌ μ£Όμ κ°μ μ΄λμμΌμΌλκΈ° λλ¬Έμ λΉν¨μ¨μ μ΄κ² λ©λλ€.
Indexing λ³κ²½ : (IJK → KIJ)
Baseline λ³΄λ€ cache λ©λͺ¨λ¦¬λ₯Ό ν¨κ³Όμ μΌλ‘ μ¬μ©νκΈ° μν΄ indexing μμλ₯Ό λ³κ²½νλ λ°©λ²μ
λλ€.
κΈ°μ‘΄ indexing (IJK) μμ (KIJ)λ‘ λ³κ²½ μ, κ°μ₯ λ§μ΄ μννλ λ§μ§λ§ forλ¬Έμ 보면 columnμ μμ§μ΄λ©΄μ μ°μ°νκΈ° λλ¬Έμ row λ₯Ό μμ§μ΄λ©΄μ μ°μ°νλ λ°©λ²λ³΄λ€ μλκ° λΉ¨λΌμ§λλ€.
κ·Όλ°, μ΄λ° νΈλ¦ μμ€μ μκ³ λ¦¬μ¦ λ³κ²½μΌλ‘ μλκ° μΌλ§λ λΉ¨λΌμ§κΉ νλλ°... νλ ¬ μ¬μ΄μ¦κ° 컀μ§μλ‘ ν¨κ³Όκ° κ΅μ₯ν λλΌλ§ν±ν©λλ€.
SIMD (Single Instruction Multiple Data) μ μ©
SIMDλ CPU μμ λ³λ ¬ μ°μ°μ νκΈ° μν multiple dataλ₯Ό νλ²μ μ°μ°νλ λ°©λ²μ
λλ€.
μ΄μ
λΈλ¦¬μ΄λ‘ μ§μ ꡬννλ λ°©λ²λ μκ³ , μ΄μ
λΈλ¦¬μ΄μ 1λ1 맀μΉλλ Intrinsic function μ μ¬μ©νλ λ°©λ²λ μμ΅λλ€. Intrinsic functionμ μ¬μ©νλ κ²μ΄ λΉκ΅μ νΈνμ§λ§ μλ£νλ³λ‘ μ¬μ©λλ ν¨μλ λ€λ₯΄κ³ νλμ¨μ΄(μ»΄ν¨ν°κ΅¬μ‘°)μ λν κΈ°λ³Έμ μΈ μ΄ν΄λκ° νμν©λλ€.
μ¦, μμ νλ νλλ₯Ό μννλ©° κ³μ°νλ λ°©μμ΄ μλλΌ, μ¬λ¬ μμμ λ¬Άμμ λ©λͺ¨λ¦¬μ μ¬λ €μ(λ³λ ¬μ ) νλ²μ κ³μ°νκΈ° λλ¬Έμ μλ ν₯μμ κΈ°λν μ μμ΅λλ€.
GPU μ¬μ© (CUDA)
GPUλ₯Ό μ΄μ©ν λ³λ ¬ νλ‘κ·Έλλ°μ νκΈ° μν΄ CUDA toolkit μ¬μ©νλ λ°©λ²μ
λλ€. λ₯λ¬λ νμ΅μ μμ£Ό κ°λ¨νκ² .cuda() λ§ μ μΌλ©΄ κ°λ¨νκ² μ¬μ©κ°λ₯νλ GPUμ΄μ§λ§, C++ μ κ²½μ°μλ dataλ₯Ό CPU-GPU κ° λ³΅μ¬νκ³ λ©λͺ¨λ¦¬λ₯Ό ν λΉνλ κ³Όμ λ€μ΄ νμν΄μ λΉκ΅μ 볡μ‘ν©λλ€.
νμ§λ§, κ°μ₯ κ²°κ³Όκ° μ’μ λ°©λ²μ
λλ€.
* κΈ°λ³Έ μμ
1)Dataλ₯Ό CPU → GPU 볡μ¬
2)GPUμμ kernel ν¨μ μ€ννμ¬ μ°μ°
3)κ²°κ³Όλ₯Ό GPUμμ CPU λ‘ λ³΅μ¬
μ€ν κ²°κ³Ό
λͺ¨λ μ€νμ (1000x1000 size matrix) * (1000x1000 size matrix) μ νλ ¬κ³± μ°μ°μ νκ· μμ μκ°(ms)μ
λλ€.
CUDA λ°©λ²μ κ²½μ° λ©λͺ¨λ¦¬μ μ¬λ¦¬λ μκ°κΉμ§ ν¬ν¨νμ΅λλ€. (κ·Έλλ μλμ μΌλ‘ λΉ λ¦
λλ€)
κ²°λ‘ λ§ μ 리νλ©΄, Cache λ©λͺ¨λ¦¬ μ κ·Όμ ν¨κ³Όμ μΌλ‘ ν λ(Indexing λ³κ²½), λ³λ ¬ νλ‘κ·Έλλ° μ¬μ©ν λ (SIMD), GPU μ¬μ©ν λ(CUDA) μ±λ₯μ΄ μ’μμ§λλ€.
CPU νμ μΌλ‘ λ΄€μ λ, Eigen λΌμ΄λΈλ¬λ¦¬κ° μ°μ° μλκ° μ’κ³ νλ ¬μ λ€λ£¨κΈ° νΈνκΈ° λλ¬Έμ μ νμ μ¬μ§κ° μμ κ² κ°μ΅λλ€.
λ°μν