같은 실행파일이 같은 os 다른 하드웨어 위에서 실행될수 있는 이유가 뭔가요?

why의 이미지

c/c++ 빌드 과정을 공부하다가 의문이 들어서 질문합니다.

c/c++ 빌드 과정이 컴파일을 통해서 네이티브 코드(기계어)로 이루어진
목적 파일들로 만들어지고 이 목적파일 들이 링킹되어서
현재 탑재된 운영체제의 형식에 맞는 실행파일이 만들어 지는 것
이라고 이해하고있습니다.

즉 실행파일은 cpu가 알아들을 수 있는 네이티브코드이며
현재의 운영체제가 자신의 형식에 맞게 추가의 네이티브 코드들을 삽입한
형태라고 이해하고 있습니다.
( 그래서 같은 실행파일이 다른 os에서는 작동되지 않는 것도 이해하고 있습니다 )

그리고 네이티브 코드는 cpu 계열에 따라 달라 질수있다는 것으로
알고 있고 목적 파일을 만들때도 cpu 계열에 맞게 컴파일이 되는것으로
알고있습니다.

그래서 궁금한 것이 어떻게 특정 cpu 위에서 빌드되어 만들어진 실행파일이
같은 os 다른 cpu에서 작동될수 있는가 입니다.

계열이 같다면 문제가 없겠지만 계열이 다르다면 작동이 안되는게
맞지 않나요...?

아무리 구글링 해도 찾을수가 없어서 여기에 질문을 올립니다. 사실 제가
전공자가 아니라 이쪽 관련 지식이 너무 부족해서.. 어떻게 찾아야
할지도 잘 모르겠습니다. 제가 뭔가를 잘못 이해하고 있는건가요?

라스코니의 이미지

native compile과 cross compile을 말씀하시는 것 같은데
컴파일러라고 대단한 것이 아니고 그냥 소프트웨어/유틸리티입니다.
코드를 컴파일해서 어떤 목적 코드/실행가능 바이너리를 만드는 것이 주 임무이지요.

특정 컴파일러를 이용해서 특정 CPU/OS 환경에서 동작하도록 하는 바이너리를 만드는 것도 그 특정 컴파일러 소프트웨어 입장에서는 매우 자연스러운 것입니다. 대다수의 개발자가 자신의 개발환경에서 실제 실행까지도 되는 코드/환경 기반으로 작업하기 때문에 약간 생소하실 수도 있고요.

그런 동작을 하는 특정 컴파일러는 cross compiler라고 해서 상용 제품이 있을수도 있고 gcc 로도 구성할 수 있습니다. 구글에 cross compile 으로 검색해 보세요.

why의 이미지

크로스 컴파일러에 대해 찾아봤는데 또 의문이 생깁니다.

크로스 컴파일러란게 존재하는 것으로 보아 비주얼 스튜디오 같은 네이티브 컴파일러로 생성된 실행파일이 다른 계열의 cpu에서도 작동할 것이라는 생각은 일단 잘못 된 것을 알았습니다.

애초에 그런 생각을 했던 것이 인텔 cpu와 amd cpu의 아키텍쳐가 많이 달라서 인텔 cpu 환경에서 생성된 실행파일이 amd cpu에서도 실행이 안될 것이다라고 생각해서 였는데 찾아보니 일부 명령어를 제외하고는 대부분 같다고 하는것을 알게되었습니다.

그러면 여기서 의문이 드는것이 그렇다면 그 일부 다른 명령어들은 컴파일러가 활용하지 못하는 것인가? 입니다... 활용했다면 정말 cpu가 달라지면 실행파일이 작동을 안할테니까요. 그래서 활용을 하지 않는다고 생각이 드는데 ... 그렇다면 애초에 cpu에 그런 추가의 명령어들을 만드는 것이 아무 의미가 없지 않나 싶어서 의문입니다.

라스코니의 이미지

MS Windows같은 OS는 상용적으로 매우 성공한 OS이기 때문에 Intel, AMD 같은 CPU 아키텍쳐에 대한 차이도 고려하고 지원하고 있습니다. 또는 어플리케이션에서도 CPU 아키텍쳐를 판별하여 별도의 library를 구동할 수도 있고요. 예를 들어 IntelCodec.dll, AMD64Codec.dll 등과 같은 식이죠. VMware 가상화 소프트웨어를 보면 Intel, AMD에 대해서 별도의 체크 옵션을 가지고 있습니다.

결론은 컴파일러에서 지원하고 있습니다. 주로 사용하시는 컴파일러 메뉴얼을 검색해 보세요.

...의 이미지

안 된다고 보는 게 옳습니다. 한 바이너리는 기본적으로 amd (내에도 여럿이 있고)나 intel (내에도 여럿이 있겠죠) 중의 하나만 지원합니다. 그나마 다행인 건 backward compatibility가 있어서 새 CPU는 옛 CPU의 instruction set을 지원합니다. 예컨대 core i7 하드웨어도 기본적으로 3년전 intel processor가 지원하던 명령어는 다 지원하는 식이죠. 따라서 최신 하드웨어에 맞게 컴파일 한 건 구형 하드웨어에서 돌아가지 않으며, 구형 하드웨어를 타겟으로 컴파일 한 건 최신 하드웨어에서는 돌아는 가지만 새로운 명령어 집합(e.g. AVX512)을 사용하지 못합니다.

그래서 보통 흔히 선택할 수 있는 옵션은 대부분의 리눅스 배포판의 바이너리 패키지들이 그렇게 하는 것처럼 최대한 generic한 머신을 타겟으로 컴파일을 하는 거구요. 이렇게 하면 당연히 신형 하드웨어의 장점을 사용할 수 없죠.

이 경우에는 동적으로 OS/CPU 아키텍쳐를 검색하는 코드는 generic한 타겟으로 컴파일 하고, 실제 돌아갈 프로그램은 (유저의 머신이 뭔지 배포판 만드는 사람은 거의 모르기 때문에) 여러 하드웨어를 타겟으로 각각 컴파일 한 뒤 여러 개를 동시에 싣습니다.

gcc는 그런 게 없는 것으로 알고, 다른 상용 소프트웨어 하나는 multi-versioning이라고 검토만 하다 팀이 거의 망했는데 거기는 hot한 function을 여러 가지 하드웨어에 대해 번역한 뒤, 런타임에 머신 종류를 디텍트 해서 해당 function으로 점프하도록 코드를 생성하려고 했습니다.

...의 이미지

기본적으로 생각하신 게 맞습니다. 리눅스 배포판들 중 binary 배포 하는 것들은 빌드할 때 보통 generic한 -march 옵션 등등을 씁니다.

이걸 피하기 위해서는 1) 엔드 유저의 환경에 맞게 컴파일을 하거나 2) 여러 타겟에 대해 컴파일 된 것을 동시에 실어놓고 런타임에 엔드 유저의 환경에 맞는 놈으로 점프하거나... 둘 중 하나라고 생각해요.

보통은 성능/저전력 등이 중요한 경우에 1)을 이따금씩 하는 것 같습니다. 2)는 MS의 Visual Studio가 그렇다고 하는 분이 계시니 그럴 것 같은데, 흔한 일이라고 보진 않습니다.

그래서 Gentoo 같은 배포판은 거의 모든 패키지를 배포자(e.g. 데비안, 우분투, 레드햇 등)가 미리 빌드하지 않고 엔드 유저의 머신에서 빌드합니다. 그런데 이 경우에는 공정하게 말해 엔지니어링 코스트가 큽니다. 제가 7, 8년째 젠투 유저인데 업데이트 한 번 하면 꼭 뭔가 문제가 생깁니다. 이건 일정 부분 젠투가 상당히 큰 유연성을 허용하기 때문에 생기는 구조적인 어려움일 겁니다. 그래서 대부분은 바이너리 패키지 기반의 배포판을 쓰되 정말 필요한 것만 소스로부터 빌드하는 걸로 알고, 소스로부터 빌드하는 비중이 그렇게 높진 않을 거라고 생각합니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.