Skip to content

Latest commit

Β 

History

History
79 lines (66 loc) Β· 5.25 KB

File metadata and controls

79 lines (66 loc) Β· 5.25 KB

Miller-Rabin-Algorithm

문제

결정적(deterministic) λ°€λŸ¬λΌλΉˆ(Miller-Rabin) μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜μ—¬ 길이가 μ΅œλŒ€ 64 λΉ„νŠΈμΈ μ†Œμˆ˜λ₯Ό μ°ΎλŠ”
ν”„λ‘œκ·Έλž¨μ„ κ΅¬ν˜„ν•œλ‹€. 베이슀(base) κ°’ π‘Žλ₯Ό λ¬΄μž‘μœ„λ‘œ μ„ νƒν•˜λŠ” ν™•λ₯ μ  λ°€λŸ¬λΌλΉˆ μ•Œκ³ λ¦¬μ¦˜κ³ΌλŠ” 달리 κ²°μ •
적 λ°€λŸ¬λΌλΉˆ μ•Œκ³ λ¦¬μ¦˜μ€ 맀우 μž‘μ€ μ§‘ν•©μ˜ μ •ν•΄μ§„ 베이슀 κ°’λ§Œ κ²€μ¦ν•œλ‹€. κ·Έ μ΄μœ λŠ” 𝑛 < 2^64이면 베이슀
κ°’ π‘Žλ₯Ό μ§‘ν•© {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}μ—μ„œλ§Œ κ²€μ¦ν•˜λ©΄ μΆ©λΆ„ν•˜λ‹€λŠ” 것이 λ°ν˜€μ‘ŒκΈ° λ•Œλ¬Έμ΄λ‹€.

ν•¨μˆ˜ κ΅¬ν˜„

학생듀이 κ΅¬ν˜„ν•  ν•¨μˆ˜μ˜ ν”„λ‘œν† νƒ€μž…μ€ μ•„λž˜μ— μ—΄κ±°λ˜μ–΄ μžˆλ‹€. 각 ν•¨μˆ˜μ— λŒ€ν•œ μš”κ΅¬μ‚¬ν•­μ€ λ‹€μŒκ³Ό κ°™λ‹€.

β€’ int miller_rabin(uint64_t n) – 64λΉ„νŠΈ 음이 μ•„λ‹Œ μ •μˆ˜ n이 μ†Œμˆ˜μ΄λ©΄ PRIME을, κ·Έλ ‡μ§€ μ•ŠμœΌ
λ©΄ COMPOSITE을 λ„˜κ²¨μ€€λ‹€. n이 2^64 보닀 μž‘μœΌλ―€λ‘œ 결정적 λ°€λŸ¬λΌλΉˆ μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•œλ‹€.

β€’ uint64_t mod_add(uint64_t a, uint64_t b, uint64_t m) – π‘Ž + 𝑏 mod π‘šμ„ κ³„μ‚°ν•˜μ—¬ λ„˜
겨쀀닀. π‘Žμ™€ 𝑏가 각각 π‘šλ³΄λ‹€ μž‘λ‹€λŠ” κ°€μ •ν•˜μ—μ„œ π‘Žμ™€ π‘μ˜ 합이 π‘šλ³΄λ‹€ ν¬κ±°λ‚˜ κ°™μœΌλ©΄ κ²°κ³Όμ—μ„œ
π‘šμ„ λΉΌμ€˜μ•Ό ν•œλ‹€. 이 경우 μ‹€μ œ 계산은 π‘Ž βˆ’ (π‘š βˆ’ 𝑏)둜 ν•˜λŠ” 것이 μ˜€λ²„ν”Œλ‘œλ₯Ό ν”Όν•  수 μžˆλŠ” 쒋은
방법이닀. λ˜ν•œ π‘Ž + 𝑏 >= π‘šμ„ κ²€μ‚¬ν•˜λŠ” κ³Όμ •μ—μ„œ μ˜€λ²„ν”Œλ‘œκ°€ λ°œμƒν•  수 μžˆμœΌλ―€λ‘œ 𝑏λ₯Ό 였λ₯Έμͺ½μœΌλ‘œ
λ„˜κ²¨ π‘Ž >= π‘š βˆ’ 𝑏λ₯Ό κ²€μ‚¬ν•˜λŠ” 것이 μ˜€λ²„ν”Œλ‘œλ₯Ό ν”Όν•  수 μžˆλŠ” ν˜„λͺ…ν•œ 방법이닀.

β€’ uint64_t mod_sub(uint64_t a, uint64_t b, uint64_t m) – π‘Žβˆ’π‘ mod π‘šμ„ κ³„μ‚°ν•˜μ—¬ λ„˜κ²¨
μ€€λ‹€. π‘Žμ™€ 𝑏가 각각 π‘šλ³΄λ‹€ μž‘λ‹€λŠ” κ°€μ •ν•˜μ—μ„œ π‘Žκ°€ 𝑏보닀 μž‘μœΌλ©΄ κ²°κ³Όκ°€ 음이 λ˜λ―€λ‘œ π‘šμ„ 더해쀀닀.
즉, π‘Ž + (π‘š βˆ’ 𝑏)으둜 κ³„μ‚°ν•œλ‹€. κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ μ›λž˜λŒ€λ‘œ π‘Ž βˆ’ π‘λ‘œ κ³„μ‚°ν•œλ‹€.

β€’ uint64_t mod_mul(uint64_t a, uint64_t b, uint64_t m) – π‘Žπ‘ mod π‘šμ„ κ³„μ‚°ν•˜μ—¬ λ„˜κ²¨
μ€€λ‹€. μ˜€λ²„ν”Œλ‘œκ°€ λ°œμƒν•  수 있기 λ•Œλ¬Έμ— ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄κ°€ μ œκ³΅ν•˜λŠ” κ³±μ…ˆμœΌλ‘œλŠ” 계산이 μ˜¬λ°”λ₯΄μ§€
μ•Šμ„ 수 μžˆλ‹€. μ•žμ—μ„œ μ •μ˜ν•œ mod_add()κ°€ μ˜€λ²„ν”Œλ‘œλ₯Ό κ³ λ €ν–ˆλ‹€λŠ” 점과 κ³±μ…ˆμ„ λ§μ…ˆμ„ μ‚¬μš©ν•˜μ—¬
λΉ λ₯΄κ²Œ 계산할 수 μžˆλŠ” β€œdouble addition” μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜λ©΄ 문제λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€. κ·Έ μ•Œκ³ λ¦¬
μ¦˜μ€ λ‹€μŒκ³Ό κ°™λ‹€.

r = 0;
while (b > 0) {
  if (b & 1)
    r = mod_add(r, a, m);
  b = b >> 1;
  a = mod_add(a, a, m);
}
return r;

β€’ uint64_t mod_pow(uint64_t a, uint64_t b, uint64_t m) – π‘Ž^𝑏 mod π‘šμ„κ³„μ‚°ν•˜μ—¬λ„˜κ²¨μ€€
λ‹€. μ˜€λ²„ν”Œλ‘œκ°€ λ°œμƒν•  수 있기 λ•Œλ¬Έμ— 이 μ—­μ‹œ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄κ°€ μ œκ³΅ν•˜λŠ” μ§€μˆ˜ν•¨μˆ˜λ‘œλŠ” 계산이
μ˜¬λ°”λ₯΄μ§€ μ•Šμ„ 수 μžˆλ‹€. μ•žμ—μ„œ μ •μ˜ν•œ mod_mul()이 μ˜€λ²„ν”Œλ‘œλ₯Ό κ³ λ €ν–ˆλ‹€λŠ” 점과 μ§€μˆ˜μ—°μ‚°μ„ κ³±
μ…ˆμ„ μ‚¬μš©ν•˜μ—¬ λΉ λ₯΄κ²Œ 계산할 수 μžˆλŠ” β€œsquare multiplication” μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜λ©΄ 문제λ₯Ό ν•΄κ²°ν• 
수 μžˆλ‹€. κ·Έ μ•Œκ³ λ¦¬μ¦˜μ€ λ‹€μŒκ³Ό κ°™λ‹€.

r = 1;
while (b > 0) {
  if (b & 1)
    r = mod_mul(r, a, m);
  b = b >> 1;
  a = mod_mul(a, a, m);
}
return r;

OpenMP μ„€μΉ˜

OpenMP (Open Multi-Processing)λŠ” 닀쀑코어 ν™˜κ²½μ—μ„œ λ³‘λ ¬ν”„λ‘œκ·Έλž˜λ°μ„ μ§€μ›ν•˜λŠ” API이닀. 이 과제
μ—μ„œλŠ” μ†Œμˆ˜λ₯Ό 빨리 μ°ΎκΈ° μœ„ν•΄ OpenMP 라이브러리λ₯Ό μ‚¬μš©ν•œλ‹€. 학생듀이 과제λ₯Ό μˆ˜ν–‰ν•˜λŠ”λ° OpenMP
에 λŒ€ν•œ 지식이 κΌ­ ν•„μš”ν•œ 것은 μ•„λ‹ˆμ§€λ§Œ 검증 ν”„λ‘œκ·Έλž¨μ„ 돌리기 μœ„ν•΄μ„œλŠ” OpenMPλ₯Ό μ„€μΉ˜ν•΄μ•Ό ν•œλ‹€.

β€’ Linux ν™˜κ²½μ—μ„œλŠ” μ„€μΉ˜ν•˜μ§€ μ•ŠλŠ”λ‹€. μ»΄νŒŒμΌλŸ¬μ— λ‚΄μž₯λ˜μ–΄ μžˆλ‹€.
β€’ macOS ν™˜κ²½μ—μ„œλŠ” λ¨Όμ € Homebrewλ₯Ό μ„€μΉ˜ν•΄μ•Ό ν•œλ‹€. 이미 Homebrewκ°€ μ„€μΉ˜λ˜μ–΄ μžˆλ‹€λ©΄ 이
뢀뢄은 κ±΄λ„ˆλ›΄λ‹€. Homebrewλ₯Ό μ„€μΉ˜ν•˜λ €λ©΄ 터미널을 μ—΄κ³  λ‹€μŒ λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰ν•œλ‹€.

% /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

Homebrew μ„€μΉ˜κ°€ μ™„λ£Œλ˜λ©΄ λ‹€μŒ λͺ…λ Ήμ–΄λ₯Ό μ‹€ν–‰ν•˜μ—¬ OpenMP 라이브러리λ₯Ό μ„€μΉ˜ν•œλ‹€.

% brew install libomp

μ• ν”Œ μ‹€λ¦¬μ½˜μ΄ νƒ‘μž¬λœ λ§₯μ—μ„œλŠ” brew λͺ…λ Ήμ–΄λ₯Ό μ°Ύμ§€ λͺ»ν•˜λŠ” 였λ₯˜κ°€ λ°œμƒν•  수 μžˆλ‹€. brew λͺ…λ Ήμ–΄κ°€
/usr/local/bin 밑에 μžˆμ§€ μ•Šκ³  /opt/homebrew/bin 밑에 있기 λ•Œλ¬Έμ΄λ‹€. /opt/homebrew/bin
을 μ‹œμŠ€ν…œ κΈ°λ³Έ μ‹€ν–‰ κ²½λ‘œμ— ν¬ν•¨μ‹œμΌœμ•Ό ν•œλ‹€. 헀더 파일과 라이브러리 파일 κ²½λ‘œλ„ gcc 컴파일러
ν™˜κ²½λ³€μˆ˜μ— μΆ”κ°€ν•΄μ•Ό ν•œλ‹€. μ‚¬μš©μž ν™ˆλ””λ ‰ν† λ¦¬λ‘œ μ΄λ™ν•˜μ—¬ λ¬ΈμžνŽΈμ§‘κΈ°λ‘œ .zshrc νŒŒμΌμ„ μ—΄κ±°λ‚˜
μƒˆλ‘œ μƒμ„±ν•œλ‹€. μ•„λž˜ μ„Έ 쀄을 μΆ”κ°€ν•˜κ³  μ €μž₯ν•œ ν›„ 터미널을 λ‹€μ‹œ μ‹œμž‘ν•œλ‹€.

export PATH=/opt/homebrew/bin:/opt/homebrew/sbin:$PATH
export LIBRARY_PATH=/opt/homebrew/lib:$LIBRARY_PATH
export C_INCLUDE_PATH=/opt/homebrew/include:$C_INCLUDE_PATH

골격 파일

κ΅¬ν˜„μ΄ ν•„μš”ν•œ 골격파일 miller_rabin.skeleton.c와 ν•¨κ»˜ ν”„λ‘œκ·Έλž¨μ„ 검증할 수 μžˆλŠ” test.c, ν—€
λ”νŒŒμΌ miller_rabin.h, 그리고 Makefile을 μ œκ³΅ν•œλ‹€. 이 κ°€μš΄λ° test.cλ₯Ό μ œμ™Έν•œ λ‚˜λ¨Έμ§€ νŒŒμΌμ€
μš©λ„μ— 맞게 자유둭게 μˆ˜μ •ν•  수 μžˆλ‹€.