C++ μμ νλ ¬κ³± μ°μ°μ ꡬνν λ, μ¬λ¬ λ°©λ²μ λ°λΌ μλ μ°¨μ΄κ° λ§μ΄ λλ€κ³ ν΄μ κ°λ¨ν μ€νμΌλ‘ μλ λΉκ΅λ₯Ό ν΄λ³΄μμ΅λλ€. νλ ¬κ³± μ°μ° κ³Όμ μ λ°λ‘ μ€λͺ
νμ§ μκ³ , κ°μ₯ λμ΄λΈν λ°©μμμ μλλ₯Ό ν₯μμν¬ μ μλ λͺκ°μ§ λ°©λ²λ€μ λ¨κ³μ μΌλ‘ μ€λͺ
ν©λλ€.
μ¬μ€ νλ ¬ μ°μ° μ λ§μ΄ μ¬μ©νλ Eigen λΌμ΄λΈλ¬λ¦¬λ₯Ό μ°λ©΄ μ΅μ νκ° μλμ΄ μμ΄μ μ€λ¬΄μμ νλ ¬ μ°μ°μ μ§μ ꡬνν΄μΌν μν©μ΄ μΌλ§λ μλμ§λ μ λͺ¨λ₯΄κ² μ΅λλ€. μμ§ κ²½νμ΄ λ§μ΄ μμ΄μ... γ
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(~) λ§νΌ μ£Όμ κ°μ μ΄λμμΌμΌλκΈ° λλ¬Έμ λΉν¨μ¨μ μ΄κ² λ©λλ€.
Baseline λ³΄λ€ c ache λ©λͺ¨λ¦¬λ₯Ό ν¨κ³Όμ μΌλ‘ μ¬μ©νκΈ° μν΄ indexing μμλ₯Ό λ³κ²½ νλ λ°©λ²μ
λλ€.
κΈ°μ‘΄ indexing (IJK) μμ (KIJ) λ‘ λ³κ²½ μ , κ°μ₯ λ§μ΄ μννλ λ§μ§λ§ for λ¬Έμ 보면 column μ μμ§μ΄λ©΄μ μ°μ°νκΈ° λλ¬Έμ row λ₯Ό μμ§μ΄λ©΄μ μ°μ°νλ λ°©λ²λ³΄λ€ μλκ° λΉ¨λΌμ§λλ€.
κ·Όλ°, μ΄λ° νΈλ¦ μμ€μ μκ³ λ¦¬μ¦ λ³κ²½μΌλ‘ μλκ° μΌλ§λ λΉ¨λΌμ§κΉ νλλ°... νλ ¬ μ¬μ΄μ¦κ° 컀μ§μλ‘ ν¨κ³Όκ° κ΅μ₯ν λλΌλ§ν±ν©λλ€.
SIMDλ CPU μμ λ³λ ¬ μ°μ°μ νκΈ° μν multiple dataλ₯Ό νλ²μ μ°μ° νλ λ°©λ²μ
λλ€.
μ΄μ
λΈλ¦¬μ΄λ‘ μ§μ ꡬννλ λ°©λ²λ μκ³ , μ΄μ
λΈλ¦¬μ΄μ 1λ1 맀μΉλλ Intrinsic function μ μ¬μ©νλ λ°©λ²λ μμ΅λλ€. Intrinsic functionμ μ¬μ©νλ κ²μ΄ λΉκ΅μ νΈνμ§λ§ μλ£νλ³λ‘ μ¬μ©λλ ν¨μλ λ€λ₯΄κ³ νλμ¨μ΄(μ»΄ν¨ν°κ΅¬μ‘°)μ λν κΈ°λ³Έμ μΈ μ΄ν΄λκ° νμν©λλ€.
μ¦, μμ νλ νλλ₯Ό μννλ©° κ³μ°νλ λ°©μμ΄ μλλΌ , μ¬λ¬ μμμ λ¬Άμμ λ©λͺ¨λ¦¬μ μ¬λ €μ ( λ³λ ¬μ ) νλ²μ κ³μ°νκΈ° λλ¬Έμ μλ ν₯μμ κΈ°λν μ μμ΅λλ€.
G PU λ₯Ό μ΄μ©ν λ³λ ¬ νλ‘κ·Έλλ° μ νκΈ° μν΄ 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 λΌμ΄λΈλ¬λ¦¬κ° μ°μ° μλκ° μ’κ³ νλ ¬μ λ€λ£¨κΈ° νΈνκΈ° λλ¬Έμ μ νμ μ¬μ§κ° μμ κ² κ°μ΅λλ€.