사람이 코딩 안하는데 어셈블리로 코딩하면 메모리는 조금만 있어도 될텐데요.
조회 4,292 · 공감 2 · 댓글 46
프로그램이 자꾸만 커지는 이유는
인간이 이해하기 쉽게 하기 위함인데,
옛날엔 어셈블리로 코딩했는데,
이게 인간 머리로는 감당이 안돼서,
C가 나왔습니다.
이게 규모가 더 커지니,
이것도 인간 머리로 감당이 안되
C++이 나왔고요.
대규모 프로젝트는 c++로 하죠.
시간이 흐르니 이제는 이기종간 이식성 문제가 대두되고,
이것도 인간이 감당이 안돼서,
java 나 프레임워크 뭐 이런 개념이 등장하면,
프로그램들이 점점 높은 cpu와 높은 메모리를 먹는 무거운 뚱땡이가 돼 버렸는데 말입니다.
이제는 인간이 이해할 필요가 없는데,
인간이 이해하기 쉬운 고급언어는 왜 필요하며, 프레임워크도 왜 필요한지 의문입니다.
다시 어셈블리 기계어로 회귀해야 하는거 아닌가 합니다.
이렇게 되면 고성능 cpu 더 많은 메모리가 필요 없으니까요
지금도 c하고 winapi로 코딩만 해도 프로그램 크기가 어마무시하게 줄어듭니다.
댓글 46
다시 하나하나 만들어야 하거든요.
첫째, 어셈블리로 코딩한다고 메모리가 필요 없어지는 게 아닙니다.
어셈블리도 결국 기계어로 변환되어 실행되는 프로그램입니다. 변수, 스택, 힙, 버퍼, 객체, 실행 상태 등 프로그램이 동작하는 데 필요한 메모리는 그대로 필요합니다.
C로 작성하든 C++로 작성하든 어셈블리로 작성하든, 동일한 기능을 수행한다면 필요한 데이터와 연산 자체가 사라지는 게 아닙니다.
고급언어를 어셈블리로 바꾼다고 데이터가 증발하는 마법은 일어나지 않습니다.
둘째, 컴파일러가 왜 존재하는지 생각해 보셔야 합니다.
컴파일러는 단순히 인간이 이해하기 쉬운 코드를 기계어로 바꿔주는 번역기가 아닙니다.
현대 컴파일러는 인간이 작성한 코드의 의미를 분석하고, 불필요한 연산을 제거하며, 레지스터를 효율적으로 배분하고, 명령어 실행 순서를 최적화하고, CPU 아키텍처에 맞는 코드를 생성합니다.
대표적으로 GCC나 LLVM 같은 컴파일러는 사람이 직접 어셈블리로 작성하는 것보다 더 효율적인 코드를 만들어내는 경우가 많습니다.
사람이 직접 어셈블리를 작성하면 최적화가 더 잘될 것이라는 생각부터가 잘못된 전제입니다.
셋째, 프로그램이 커지는 이유가 단순히 고급언어 때문은 아닙니다.
프로그램이 커지는 주요 원인은 기능의 증가, 지원해야 할 하드웨어와 운영체제의 다양성, 보안, 호환성, 오류 처리, 사용자 인터페이스, 네트워크 통신 등 요구사항이 늘어나기 때문입니다.
이것을 전부 어셈블리로 작성한다고 해서 없어지는 게 아닙니다.
오히려 같은 기능을 구현하기 위해 작성해야 하는 코드와 유지보수 비용이 폭증할 수 있습니다.
넷째, 프레임워크는 CPU와 메모리를 낭비하기 위해 만들어진 게 아닙니다.
프레임워크는 반복적으로 구현해야 하는 기능을 재사용하고, 복잡한 시스템의 구조를 통일하며, 개발자들이 동일한 문제를 매번 처음부터 해결하지 않도록 하기 위해 존재합니다.
물론 프레임워크가 추가적인 오버헤드를 발생시킬 수 있습니다. 그렇다고 모든 프레임워크가 불필요한 것은 아닙니다.
그 오버헤드와 개발 시간, 유지보수 비용, 안정성 사이에서 합리적인 선택을 하는 것이 소프트웨어 엔지니어링입니다.
다섯째, C와 WinAPI로 작성하면 프로그램 크기가 작아진다는 것과 어셈블리로 회귀해야 한다는 주장은 전혀 다른 이야기입니다.
C와 WinAPI는 불필요한 런타임이나 무거운 프레임워크에 의존하지 않고도 프로그램을 만들 수 있는 훌륭한 선택입니다.
하지만 C 역시 컴파일러를 사용합니다. 그리고 C 컴파일러가 생성하는 기계어가 반드시 사람이 작성한 어셈블리보다 비효율적인 것도 아닙니다.
마지막으로 가장 중요한 부분입니다.
소프트웨어의 목적은 어셈블리 코드를 최대한 적게 사용하는 것이 아닙니다. 주어진 하드웨어 자원으로 필요한 기능을 정확하고, 빠르고, 안정적으로 구현하는 것입니다.
성능이 중요하다면 실제 프로파일링을 통해 병목을 찾고, 불필요한 메모리 할당과 연산을 제거하고, 알고리즘과 데이터 구조를 개선하면 됩니다.
정말 어셈블리가 더 효율적인 부분이 있다면 그 부분만 어셈블리로 최적화하면 됩니다.
모든 프로그램을 어셈블리로 작성하자는 것은 마치 자동차를 더 가볍게 만들겠다고 모든 부품을 수작업으로 제작하자는 주장과 비슷합니다.
기술의 발전은 인간이 기계어를 직접 작성하지 않아도 더 효율적인 프로그램을 만들 수 있게 하는 방향으로 이루어져 왔습니다. 그런데 다시 기계어로 돌아가자는 것은 최적화와 추상화의 발전을 거꾸로 이해한 주장입니다.
8비트 컴퓨터 시절엔 C로 짜면 너무 커져서 다 어셈을 사용했습죠. 그당시 나온 프로그램은 다 어셈으로 개발된겁니다.
쥐피티 냄새가...
어떤 기술의 발달로 모든 부품을 수작업으로 만드는 비용과 시간을 0에 가깝운 시간에 마법처럼 할 수있다면 안하실껀가요?
저라면 제게 최적화된 형태로 자동차를 만들어서 탈 것 같은데
세상에 공짜는 없어요. 어셈블리로 한다고해서 코드 절약되는건 한계가 있습니다. 코드 파악이 힘들어질 뿐이죠. LLM도 결국 메모리에 올려야 파악을 하기때문에 어셈블리를 다 올리려면 더 많은 메모리가 들겠죠.
지금 글의 이유가 맥락과 전혀 관련이 없는게
기계가 언어를 작성할 것인데 왜 프레임웍이니 뭔 소릴 하시는 건지..
어차피 기계가 작성하고 기계가 확인하고 기계가 돌릴건데.
인간의 개념이 왜 필요한건지요?
다른 컴퓨터 구조를 생각해보자면 인간의 뇌는 메모리가 연산까지 떠앉는 구조입니다.
윗 댓글 읽은 거 시간낭비라서 짜증나네요
사람이 짜기엔 극안인데, AI는 가뿐하게 짜죠..
Rust로 짜고 있군요… 새로 알아가네요
그런데 말씀하신 주장은 컴파일러의 존재 이유를 간과하고 있는 것 같습니다.
C든 C++이든 고급언어로 작성한 프로그램은 컴파일러를 거쳐 결국 CPU가 실행할 기계어로 변환됩니다.
즉, CPU 입장에서는 사람이 C로 작성했는지 어셈블리로 작성했는지가 중요한 게 아닙니다. 최종적으로 생성된 기계어와 프로그램이 사용하는 데이터 및 실행 환경이 중요합니다.
오히려 현대 컴파일러는 레지스터 할당, 인라이닝, 데드 코드 제거, 루프 최적화 등 사람이 직접 어셈블리로 작성할 때 놓치기 쉬운 다양한 최적화를 수행합니다.
물론 JVM이나 무거운 프레임워크처럼 추가적인 메모리 오버헤드를 발생시키는 실행 환경도 있습니다. 그렇다면 불필요한 런타임이나 프레임워크를 제거하고 네이티브 컴파일 언어를 선택하면 되는 문제입니다.
그런데 여기서 왜 어셈블리로 회귀해야 한다는 결론이 나오는지 모르겠습니다.
C로 작성하고 최적화 옵션을 적용해 컴파일한 결과가 직접 작성한 어셈블리보다 작거나 빠른 경우도 많습니다.
결국 메모리를 줄이고 싶다면 어떤 언어를 사용했느냐보다 실제 메모리 사용량과 실행 성능을 측정하고 병목을 최적화하는 것이 먼저 아닐까요?
컴파일러가 존재하는 이유 자체가 사람이 기계어를 직접 작성하지 않으면서도 효율적인 실행 코드를 얻기 위해서입니다.
열받아 윈도우 11도 그냥 다 어셈으로 다 짜버리면 안될까 생각해 봤습니다.
본문에서
C++은 대규모 프로젝트에 사용되는게 아니고 고성능 프로젝트에 부분적으로 사용됐는데 최근 ai가 c++을 너무 잘 다뤄줘서 다시 활용도가 높아지는 것 같습니다.
또 본문 마지막에 winapi를 쓰면 프로그램 파일크기가 작아지는 이유가 뭐냐하면 api의 정의부는 이미 만들어진 dll이 system폴더에 있고 컴파일한 바이너리는 api의 포인터들만 가지고 있기 때문입니다. 실행하면 system dll에서 필요한 코드들을 메모리에 올립니다. 마찬가지로 프로그램의 크기와 메모리 할당크기는 크게 관계가 없습니다.
기본적으로 연구된 자료구조, 데이터베이스 스키마, 알고리즘 등등은 언어를 떠나서 현재 컴퓨터 구조에서는 충분히 성숙해 있어서 어셈블리가 답은 아니죠.
AI를 위해 하드웨어 아키텍처 자체를 완전히 바꾼다면 모르겠네요. 그런 세상엔 제가 먹고 살 일이 없는 세상이라 안 왔으면 좋겠네요;
ai 입장에서 어셈블리보다 더 효율적인 방법이 있을거 같기도 하고,
단순히 메모리만 중시하지 않을거 같기도 해서요.
미래의 ai에게는 코딩을 한다거나 개발을 한다거나 프로그램을 돌린다거니.. 혹은 프로그래밍 언어가 무엇이냐라거나...
이런 개념 자체가 인간과 완전히 다를수도 있겠거니... 싶더라고요.
툭 까놓고, 지금은 ai의 과도기도 아니고, 초입도 아니고, 그저 시작지점 아니겠습니까?
바둑 AI의 발전 과정에서 보면, 인간의 기보 학습(지도학습)에서 시작해, AI끼리 스스로 대국하며 성장하는 ‘독학(강화학습)’ 방식으로 진화했듯이
ai가 유지보수성을 무시하고 더 효율적인게 어셈블리라고 스스로 판단한다면 어셈블리로 짤 수도 있겠죠...
그런데 어셈블리로 짜면 이기종 이식이 어려워지지 않나요?
llm이 지들 효율에 맞쳐 언어를 만들고 그걸로 소통 작업하는 시대
인간은 llm이 어떤 작업을 하는지 모니터링도 못하고 따라만 가는
그런날이 올때기 새로운 세상이죠
현재는 LLM 도 결국 사람의 지능을 모사한거라
사람이 이해하기 좋은게 LLM에게도 이해하기 좋죠.
바닥부터 다 짜다보면 LLM도 컨텍스트도 부족하고 어텐션도 잘 안되지 않을까요?
바이브코딩 하는 건 좋은데 결과물에 대한 소유와 책임은 인간이 갖는 겁니다. 인간이 쉽게 이해못할 코드는 여전히 쓰레기에요.
간단히 말해 최적화와 호환성이 박살나요.
일단 결론만 얘기드리자면, 똑같은 프로그램을 어셈블리어로 짜느냐, C++로 짜느냐는 메모리가 절약되는 것과 거의 관계가 없다고 보시면 됩니다. 메모리에 올라가는 뭐 실행파일 크기 몇백kb + 런타임 초기화 비용 정도 차이는 있긴 하겠네요. 그런데 그건 뭐 위성이라던지 초소형 임베디드 같이 특수한 환경에서나 의미 있지 메모리가 수십기가씩 있는 일반적인 PC환경에서는 으미 없는 수준입니다.
메모리 사용량은 프로그램 작동 구조상 메모리에 올리는 데이터 구조, 데이터 크기의 문제와 효율적인 사용, 할당과 해제를 제대로 하고 있느냐의 문제인거지 어떤 언어로 만들어졌냐가 중요한게 아닙니다. 위에 댓글에 나온 러스트도 메모리의 안전성에 장점이 있는 것이지 절약과는 그다지 상관 없습니다.
AI가 어셈블리어로 작성해서 얻는건 컴파일 시간의 이득 정도입니다. 그걸 위해서 안게될 손해는 훨씬 더 크구요.
그리고 LLM 입장에서도 학습을 고급언어로 학습하는 게 더 낫습니다.
같은 토큰이면 의미론 적으로 알고리즘을 응축시키는 힘 자체가 고급언어 쪽이 비교도 안되게 뛰어나니까요.
정말로 최적화에 목을 매야 하는 상황이 있고.. 그것을 고려하면 LLM이 학습을 하더라도.. LLVM IR 정도 까지는 학습을 할 수 있겠죠.
그리고 어셈블리는 CPU 아키텍처 종속이라 다양한 플랫폼 마다 코드를 새로 작성해야 하고, 새로운 보안문제나 오류를 수정할 때 복잡해집니다. 지금의 AI 수준이 이기종간의 동일성을 100% 보장하지도 못합니다.(미래엔 가능할지도요) 그래서 아직까지는 플랫폼은 컴파일러에 맡기고 논리적 구조에 집중하는 방향이 맞다 봅니다.
작상하신분을 보니.. 음... 이해가 됐습니다.