의미가 분명한 자료구조 vs 절차형 기계의 효율

차리서의 이미지

언어의 구문적 분명성이야 기계어 등을 제외한 대부분의 현존 언어들이 대체로 갖추고 있지만, 의미상의 분명성이 얼마나 검증될 수 있는가 하는 문제는 아직까지는 각각의 언어들마다 적지 않은 차이가 있어 보입니다. 따라서 비슷해보이는 자료구조를 기술하는 방법 뿐만 아니라 그렇게 기술된 의미의 분명성 또한 각 언어마다 다르겠죠.

간혹 Gnu MP 라이브러리를 쓸 수 없는 특수한 상황에 처할 경우에 대비해서 (실제로 그런 경우가 있을지는 모르겠습니다만), 단순한 아류작 정도 되는 Reeseo's MP 라이브러리를 간단히 만들어봤었습니다. 의미 체계의 정형성을 포기할 생각이라면야, 설계도의 의미를 왜곡해가며 구현한다든가 아니면 아예 의미론 자체를 무시하고 설계해버리는 등 효율을 몇 배로 올릴 수 있는 여러가지 방법(혹은 꽁수)들을 쓸 수 있었겠죠. 하지만, 이 라이브러리를 딱히 효율이 절실한 중요한 일에 투입할 것도 아니고 어디까지나 비상용이자 거의 장난에 가까운지라, 그냥 밑바닥부터 하나 하나 정형적인 의미 체계를 유지하여 설계하고 그 설계도의 의미 그대로를 (전형적인 '가난한 C 프로그래머' 관점에서 보자면 단순 무식 지랄스럽게) 코드로 옮겨 구현하고자 노력했더랬습니다. C 언어의 언어적 특성 상 설계도의 의미를 모두 코드에 투영시키는 과정이 (특별히 이런 것에 유리한, 예를 들어 일부 함수형 언어들 등에 비해) 상당히 어렵고 고달픈 작업이었을 뿐더러 언어 자체가 그 과정의 옳바름을 충분히 검증해주지도 못했지만, 거의 오기로 한 번 시도해봤었죠. 게다가, 의미적 정형성을 유지하는 것이 적지 않게 고달팠음에도 불구하고 끝까지 포기하지 않았던 또 하나의 중요한 이유는, 바로 'C 언어는 오랜 세월동안 컴파일러가 잘 다음어져온 언어고, gcc 등의 현대적 컴파일러는 어차피 무척 효율적인 절차형 기계용 이진 코드를 만들어주니까 약간의 효율 손해는 큰 문제가 없으리라'는 편견(?)이 작용했다는 것입니다.

결과물은 잘 작동했습니다. 여기서 잘 작동했다는 말은 '오동작 없이 예정된 설계 대로만 동작했으며, 앞으로도 그러리라 믿어졌다'는 뜻입니다. 그런데, 한 가지 예상치 못한 일이 벌어졌습니다. 속된 말로, 효율이 정말 끝장으로 나쁘더라는 것이죠. '왜' 그렇게까지 극단적으로 효율이 떨어졌는지는 궁금하지 않았습니다. 이유야 처음부터 잘 알고 있었으니까요. 의외였던 것은 '그렇게까지 극단적으로' 효율이 떨어졌는가였습니다. 그렇게 심할줄은 몰랐거든요. 팩토리얼 1000을 구하는데, P2-166 128M Win98SE 환경에서 dmc (Digital Mars C Compiler)로 컴파일된 프로그램이 약 8초~10초, P3-450 128M Linux 2.4.x 환경에서 gcc로 컴파일된 경우 약 5~7초, P3-750 384M WinXP-CygWin 환경에서 CygWin-gcc로 컴파일된 경우 약 3~5초가 걸리더군요. :cry:

그러면, 역시 폰 노이먼 절차형 기계 상에서는 결국 의미를 부여하고 검증하는 부하가 배보다 훨씬 큰 배꼽 역할을 할 수 밖에 없다는 이야기일까요? 꼭 그렇지만은 않을수도 있다는 것을 ghc (Glasgaw Haskell Compiler)로 컴파일된 간단한 factorial 프로그램을 통해 알 수 있습니다. 과연 gcc로 C 코드를 컴파일한 프로그램보다 ghc로 Haskell 코드를 컴파일한 프로그램이 반드시 느릴까요? 꼭 그렇지만도 않은 것 같거든요. 그만큼 ghc 컴파일러가 충분히 연구되고 잘 만들어진 컴파일러라는 뜻일 것이고 (아마도 함수형 선언들로부터 normalize 등을 통해 최적화된 절차형 이진 코드를 만드는 과정이 역시 엄청나게 잘 다듬어져 있는 듯합니다), 그만큼 제가 더 공부해야할 것들이 산처럼 많다는 뜻이겠죠. ^^;

물론, 제가 만든 RMP 라이브러리에서 '숫자', '수', '자리수', '연산'을 이야기하는 과정과 Haskell에서 Num, Integral 타입클래스와 Integer 타입을 이야기하는 과정에는 상당한 차이가 있긴 합니다. 예를 들어 RMP 라이브러리는 digit와 integer를 따로 말하며 integer에는 digit에 없는 cipher라는 개념이 있고 digit는 한 자리 integer와는 위상 자체가 다르게 되어있죠. 이 과정에서 기계와 C언어 자체가 불분명한 의미로 제공하는 각종 자료형들에는 거의 의존하지 않고 있습니다.

여기서 한 가지 상념이 떠오릅니다. 만일 폰 노이만 기계와는 달리 전혀 절차적이지 않고 상태 변화에 의존하지 않는 새로운 기계가 있어서, 절차적이지 않은 선언들을 특별한 절차화 기법 없이도 최적(?)으로 기계에 알려주고 결과를 평가할 수 있다면, 그래서 이 기계에 C 언어 컴파일러를 이식하려면 오히려 역사적으로 발전해온 모든 절차형 언어의 컴파일러 이론을 거의 버리고 거꾸로 절차적 대입과 참조의 명령 배열을 역으로 함수형 선언과 평가의 집합으로 바꾸는 기법과 그에 따른 비용이 필요하다면, 일반적으로 말하는 속도와 저장 공간의 효율이라는 것 역시 위와는 반대되는 상황도 벌어질 수 있지 않을까 하는 것이죠. 물론 이미 연구 중인 분야인 것은 알고 있습니다만, 이런 연구의 진행 상황이나 지금까지의 성과 등을 자세히 접하기가 그다지 쉽지는 않군요.

제가 연구하는 (정확히는, 하기 시작한) 분야도 이와 약간의 간접적 연관성이 있긴 하지만, 혹시 이 게시판에서 현재 활동하시는 분들 중에 상당히 직접적으로 이 분야를 깊게 연구하고 계신 분이 있는지 궁금합니다. 그런 분들의 이야기(어떤 것이든)를 들어보는 것도 재미있을 것 같구요.

cedar의 이미지

이런 심오한 주제는 토론 게시판으로 옮기심이 좋을 듯하네요.

wildkuz의 이미지

:twisted:

전 학부만 마치고 생업에 뛰어들어서 이론적으로 윗분처럼 잘 알지는 못합니다만 제목에 자료구조라는 말보단 data type이란 말이 더 어울릴 듯 하네요.

만일 폰 노이만 기계와는 달리 전혀 절차적이지 않고 상태 변화에 의존하지 않는 새로운 기계가 있어서
거꾸로 절차적 대입과 참조의 명령 배열을 역으로 함수형 선언과 평가의 집합으로 바꾸는 기법과
-> 물론 물리적으로 그런 기계가 존재하지 않겠지만, 우리가 현재 Haskell같은 순수한 함수형언어를 쓰는 환경자체를 위와같은 기계라고 생각하면 되지 않을까요?
그러면 자연히 위의 기법은 Haskell의 Monad처럼 되지 않을까 하는 생각이 듭니다.

Haskell에서 Num, Integral 타입클래스와 Integer 타입을 이야기하는 과정
-> 위의 말을 제대로 이해하려면 Lambda Calculus같은 이론부터 잘 알아야 하는데 윗분 글에 대답해 줄 수 있는분이 그리 많지는 않을것 같습니다.
전에 kldp게시판에서 보니, 여긴 c언어같은 명령형 언어를 선호하는 분들이 많은것 같더군요.

You may say I'm a dreamer.
But I'm not the only one.

thedee의 이미지

Quote:
혹시 이 게시판에서 현재 활동하시는 분들 중에 상당히 직접적으로 이 분야를 깊게 연구하고 계신 분이 있는지 궁금합니다. 그런 분들의 이야기(어떤 것이든)를 들어보는 것도 재미있을 것 같구요.

저는 전혀 아닙니다만... 님의 말씀이 재미있기도 하고 이해하기가 어렵기도 해서 더 많은 이야기와 정보를 들어보고자 답글을 답니다.

제가 이해한 대로라면:
1) 씨 언어로 수치 연산용 라이브러리를 하나 만들었는데 최적화 부분은 전혀 신경쓰지 않고 알고리즘의 의미만 그대로 옮겼다.
2) 그랬더니 헤스켈같은 언어로 같은 작업을 한 결과와 비교했을 때보다 결코 낫지 않은 성능이 나와 버렸다.(씨로 만들었는데도!)
3) 헤스켈같은 언어는 의미에 충실하게 코드를 만들어도 내부적으로는 씨 코드가 만들어 내는 것과 유사한 효율적인 이진 코드를 생성해 내도록 컴파일러가 진화되어 왔다.
4) 그러면 헤스켈의 함수형 스타일 소스 코드를 (씨 스타일의 절차지향적인 이진 코드로 생성해내지 않고) 원래 스타일 그대로 이진 생성하면서도 효율성을 유지할 수 있는 비-노이만 스타일의 기계는 없을까?

물론 저는 모릅니다만... 그런 쪽으로 연구가 되고 있나요? 그 아이디어 자체가 궁금합니다. 비-노이만 기계라는 아이디어... 심볼릭스같은 게 그런 건가요? (나 모름)

vacancy의 이미지

factorial 연산은,
von neumann machine/非 von neumann machine을 비교하기위한
좋은 예제가 아닌 것 같은 느낌이 듭니다.

절차적인 언어가 아니더라도,
factorial 연산은 특별히 최적화할 방법이 없지않나요 ?
자료구조를 잘 만들어서 보다 빠르게 할 수는 있겠지만,
非 von neumann machine을 도입한다고 해서 좋아질 예제는 아닌것 같네요.

winner의 이미지

학술적인 문장이군요. 장문의... -_-

Dragon Raja 의 타이번 하이시커의 책이 떠올랐습니다.

weongyo의 이미지

차리서 wrote:
'C 언어는 오랜 세월동안 컴파일러가 잘 다음어져온 언어고, gcc 등의 현대적 컴파일러는 어차피 무척 효율적인 절차형 기계용 이진 코드를 만들어주니까 약간의 효율 손해는 큰 문제가 없으리라'는 편견(?)이 작용했다는 것입니다.

편견이 아니라, 컴파일러를 잘 모르기 때문인 것 같군요. 그리고 컴파일러가 해줄 수 있는 역활의 한계두요.

님께서 생각하는 의미가 분명한 자료구조는 컴퓨터가 생각하는 것과 다릅니다.
나의 입장에서 생각하지 마시고 계산하는 컴퓨터의 입장에서 생각해서 프로그래밍하시면 좋을 하군요. 님께서 생각한 계산을 직접 수행하는 것은 님이 아니라 컴퓨터입니다.

님께서는 컴파일러가 IQ 가 최소 80 이상에 중학교 수학을 기본적으로 숙지한 프로그램으로 생각하는 것 처럼 보입니다.

asiawide의 이미지

학교다닐 때 공부를 제대로 안해서 -_-; 좀 이해가 안가서 질문을 몇가지 드리겠습니다.

폰 노이만 기계의 의의는 '프로그램 로딩 방식' 이라고 알고 있습니다. 프로그램을 저장장치에 담아두고 버스를 통해서 연산장치로 불러들여서 처리하고 결과를 다시 저장장치나 출력장치에 보내는 우리가 지금 사용하는 컴퓨터의 모델을 제안한 것이죠. (다들 아시는 이야기해서 죄송합니다 -_-;)

그런데 폰 노이만 '절차형'(?) 기계라는 것이 무엇을 말씀하시는지 잘 이해가 가지를 않습니다. 연산장치가 바이너리의 연속인 코드를 해독해서 일을 처리하는 것을 말씀하시는 것인가요?

폰 노이만 기계에서 연산장치를 글쓰신 분이 생각하시는 형태로 바꾼다고 해도 전체 시스템은 여전히 폰 노이만 기계가 아닌가요? -.-?

제가 볼때 글쓰신 분이 제안하신 생각은 폰 노이만 기계 보다는 새로운 자동장치 이론쪽에 가까운것 같습니다. 다른 분들의 생각은 어떤신지 궁금하네요...

tmdcjsl의 이미지

의미가 분명한 자료구조 vs 절차형 기계의 효율

길어서 다 읽지 않았습니다.
랭귀지가 어쩌고 저쩌고 하는데...

허나 이것은 확실하죠.

의미가 분명한 자료구조가 100배는 중요하다는 것입니다.

적어도 약간의 자존심이 라도 있는 프로그래머는 반드시 자료구조를 설계하고 코딩에 들어갈 것입니다.

빠른 속도를 가진 알고리즘 구현을 위해서는 반드시 자료구조를 꼼꼼히 설계해야 합니다.

리스트, 벡터, 트리.... 이런 개념이 발표된지는 몇십년전입니다. 그러나 이 것의 중요성은 말할 필요도 없지요.

winner의 이미지

차리서 wrote:
단순한 아류작 정도 되는 Reeseo's MP 라이브러리를 간단히 만들어봤었습니다.

이건 아류작이 아니라 대단히 독창적인 것 같은데요.
GNU Multi Precision 은 속도를 가장 중시해서 제작한 것으로 압니다.
하지만 차리서씨가 만든 것은 수학적 접근을 통해서 만들었으니...

그런데 그 source 올리실 생각없나요?
정말 멋질 것 같습니다.
5초에 1000! 을 구하셨다니... 쩝...
제가 보기에는 상당한 효율적인 것 같습니다.

vacancy wrote:
factorial 연산은,
von neumann machine/非 von neumann machine을 비교하기위한
좋은 예제가 아닌 것 같은 느낌이 듭니다.

GNU Multi Precision 이야기가 나온 것은 봐서는 계승을 구하는 것 이전에 임의정밀도 수의 곱셈연산자체에서 성능이 무지하게 떨어지는 것이 아닐까 싶습니다.
곱셈내에서 Neumann Machine 과 Post Neumann Machine 의 차이는... 글쎄요...
저는 Post Neumann Machine 을 잘 모르니...

그런데 Post 라고 하는 거 맞나요? -_-... 대게 한국어로 번역할 때 탈 노이만 기계라고 하던데...

asiawide wrote:
폰 노이만 기계의 의의는 '프로그램 로딩 방식' 이라고 알고 있습니다.

제가 아는 바로는 여기에 더해서 차례대로(절차적으로) loading 을 수행한다고 알고 있습니다.
더욱 골 때리는 점은 Bus 구조로 공유한다는 거죠.
Neumann 이 처음으로 Computer Architecture 를 완성했던 때와는 달리 지금은 memory 가 상당히 계층화되었는데 여기서 주요관점은 memory 와 CPU 의 연동인 것 같습니다.
register 의 각 state(bit 라고 하는 것이 더 적당할까요?)들은 동시처리가 되는 것 같습니다만 memory 는 동시처리는 안 되죠.
따라서 shift 연산이 register 상에서 bit-shift 는 CPU cycle 에 의해 상수시간으로 결정됩니다만 memory 에 배열로 존재하는 data 는 요소 수만큼 시간이 걸리는 걸테구요.

결국 동시처리가 불가능하다는 것이 Neumann Machine 의 한계로 아는데 맞나요?

Post Neumann Machine 이 구체적으로 어떤 것인지 전 모르겠습니다만 거의 꿈의 computer 로 생각하고 있습니다. 이것이 완벽하게 나온다면 Computer Science 는 모두 바뀌겠죠.
자료구조는 물론이고, Algorithm, Compiler, Programming Languge 몽땅 말입니다.

최근 양자(Quantom) Computer 를 이야기하는 분들이 있는데 이것도 그런 것 같군요..

asiawide의 이미지

좋은 글 잘 봤습니다. 용량이 작고 갯수간 제한된 레지스터의 경우에는 각 비트마다 래치를 사용해서 1 클럭으로 시프트를 할 수 있는데 (아닌가요? 틀리면 고쳐주세요 -_-; ) 메모리의 경우에는 이렇게 설계할 수 없어서 몇(?) 클럭이 필요한게 아닌가요?

물론 저장장치인 디스크와 메모리의 자료는 시프트를 하려면 버스를 따라 메모리와 cpu 를 왔다갔다 해야 되기 때문에 클럭이 더 많이 필요하겠죠. 이렇게 저장장치의 데이터를 CPU 로 가져오지 않고 직접 조작할 수 없는 것이 문제겠네요.

함수형 언어를 써보지 못해서 감이 오지는 않는데 이게 왜 함수형 언어의 처리에 적합한(?) 바이너리를 생성하는데 문제가 되는것이죠??

wildkuz의 이미지

:twisted:

처음 글쓰신 분이 말하는 기계에는 상태(state)가 없습니다. 즉, 당연히 폰 노이만식 언어의 특징인 asignment가 없어지는 거죠. 중,고등학교때에 배운 수학을 생각해 보세요.
x=1 이라고 선언하면 x는 늘 1입니다. x에 1을 대입해서 1이 아니죠.
x + 2 = 3 에서 우리는 x가 1이란걸 금방 알 수 있죠. 즉, 이런 걸 풀때에도 x가 앞에는 0이었다가 나중에 1이 되는게 아니라 이 환경에서 늘 x는 1이란거죠.

수학에서 정수는 무한대입니다. 2 또는 4 바이트라서 65535를 넘을까 고민할 필요가 없죠. 하지만 c 같은 언어를 알고리즘을 생각하면 고민해야 합니다. 함수형 언어로 문제를 푼다면 앞의 문제도 사실 거의 고민하지 않고 알고리즘을 생각하게 되죠.

팩토리얼 문제를 풀때 c 같은 언어로 for나 while을 써서 문제를 풀고 그 알고리즘을 한번 수학적으로 증명해 보십시오. 결코 쉬운일이 아닐겁니다. 하지만 함수형 언어를 쓰면 수학적 정의를 그대로 써서 문제를 풀 수 있습니다. 그리고 중요한건 비교적 쉽게 귀납적으로 증명도 할 수 있겠죠.

소프트웨어의 위기가 어디서 오는지 한번 고민해 보십시오. N. Wirth가 말한 goto 문제만이 전부가 아닙니다.
잘못 이해하시는 분들이 많아 전 힌트만 드렸습니다.

p.s. functional pardigm에 맞는 기계라.......ㅎㅎㅎ

You may say I'm a dreamer.
But I'm not the only one.

죠커의 이미지

아. 차리서님이 헤스켈 문서를 번역하셨죠? 잘 보고 있습니다. :-)

게시판만 만드시면 딱 헤스켈 커뮤니티를 만들수 있을텐데요.

Together의 이미지

CN wrote:

아. 차리서님이 헤스켈 문서를 번역하셨죠? 잘 보고 있습니다. :-)

혹시 그 하스켈 문서 어디 있는지 아시나요? wiki에 찾아 봤는데 못찾겠네요.

- 험한 세계에서 자주국방 없는 경제력은 경비없는 은행이다. -

sliver의 이미지

Together wrote:
CN wrote:

아. 차리서님이 헤스켈 문서를 번역하셨죠? 잘 보고 있습니다. :-)

혹시 그 하스켈 문서 어디 있는지 아시나요? wiki에 찾아 봤는데 못찾겠네요.

차리서님 홈페이지에 있더군요..

저도 고맙게 잘 보고 있습니다..ㅎㅎ