운영체제마다 랜덤 함수의 결과가 다르다!

개요

논문에 들어갈 Figure를 작성하던 중에 Reproducibility(논문의 실험 재현성)가 필요해졌다. 그러나 일부 실험에서 랜덤 함수가 사용이 되어졌기 때문에, 랜덤 함수의 시드값을 고정하는것이 필요해졌다. 그래서 랜덤 시드를 모두 고정시키고, 다른 사람들에게 논문의 실험 재현성이 나타나는지 검증 요청했지만, 일부 사람들로 부터 재현에 실패하였다는 이야기를 듣게 되었다.

누군가는 재현에 성공했지만, 누군가는 재현에 실패하였다는 이야기를 듣고 왜 그런지 원인 파악하게 되었다. 이 과정에서 얻은 문제점과 경험에 대해 공유하고자 한다.

본론

가장 큰 원인으로는 내부 커널에서 구현된 Random 함수가 근본적으로 다르다!

이것이 무엇을 뜻하냐면, 리눅스 커널에서 구현된 randsrandSVr4, 4.3BSD, C89, POSIX.1-2001. 란 표준을 따르고 있다.

하지만 맥의 경우에서는 근본적으로 OpenBSD 라는 기반으로 구현이 되어 있는데, OpenBSDArc4Random 를 기반으로 구현이 되어져 있다. 그렇기 때문에 리눅스와 맥의 경우에는 근본적으로 랜덤함수의 구현 방식이 다르다.

필자의 경우 윈도우는 도대체 어떠한 랜덤 함수가 구현되어 있는지 알고 싶었지만, 윈도우는 따로 찾지 못하였다. 그렇기 때문에 사전에 알고 계신 분이 있으시다면 메일이나 댓글을 통해 알려주신다면 감사드립니다.

실험

가장 간단하게 아래의 코드를 10회 반복하였을 때 운영체제 마다 어떠한 결과가 나타는지 확인을 해볼 것이다.

먼저 결과부터 알려드리자면 운영체제마다 모두 결과가 상이하게 나타났다.

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) { 
    srand(10);
    for (int i = 0; i < 10; i++) printf("%d\n", rand());
    return 0;
}

실험 결과

우선 여러 플랫폼에서 실험한 결과이다. 윈도우의 경우 Win10으로 실험이 진행이 되었고, 리눅스의 경우에는 glibc 2.23으로 실험이 되었다. Sonoma 14.2 (23C64)으로 진행이 되었다는 점을 먼저 밝힌다.

시도 맥북 리눅스 윈도우
01 168070 1215069295 71
02 677268843 1311962008 16899
03 1194115201 1086128678 3272
04 1259501992 385788725 13694
05 703671065 1753820418 13697
06 407145426 394002377 18296
07 1010275440 1255532675 6722
08 1693606898 906573271 3012
09 1702877348 54404747 11726
10 745024267 679162307 1899

해결책

필자의 경우에는 C/C++ 언어로 주로 개발하였다보니, C/C++에 대한 해결책 밖에 따로 생각이 나지 않는다. 만약에 다른 언어도 통하는 범용적인 해결책으로는 독자적인 랜덤 함수를 구현하여 모든 플랫폼에 배포하는것 말고는 방법이 생각이 나지 않는다.

물론, 보안상으로 랜덤 함수가 예측이 되지 않고 진정한 무작위 난수인 것이 최고이다. 그렇기 때문에 최근에는 하드웨어 난수 생성기를 사용하고 있는 실정이다. 그래서 랜덤함수가 시드를 통해 예측이 되지 않는것이 사실상 더 좋은 선택지 이겠지만 말이다.

만약 C/C++에서 랜덤함수를 개인적으로 표준화를 진행한다면, glibclibcxx를 커스텀하고, 이를 링킹하도록 만드는것이 가장 최고이지 않을까? 라는 생각이 든다. 그렇게만 한다면 맥에서나 리눅스에서 동일한 glibc의 버전을 사용하는 것이므로 근본적으로 동일한 결과가 나타날것이라 예측이 된다.

그것이 아니라면 scretch 컨테이너 하나 만들고, 커스텀화된 glibc를 삽입하는것도 하나의 방법이 될지도 모른다.




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • 위노그라드 알고리즘 정리
  • 외부에서 내부망으로 접근하기 위한 3가지의 방법론
  • GIST Developers' Night 2024에 연사로 참가하고 나서
  • JVM 밑바닥까지 파헤치기 책을 읽고
  • 고성능을 위한 언어 C++ 책을 읽고나서