삽질했습니다.
글쓴이: leonid / 작성시간: 화, 2007/02/06 - 1:42오전
간단한 프로그램을 만드는 도중에
셀 상하좌우에 벽을 넣는 과정이 있는데
저는 1 : 상, 2 : 우, 4 : 하, 8 : 좌
로 설정해놓고 적절히 더해서 원하는 상태를 만들기로 했습니다.
예를 들어서 셀의 위쪽과 오른쪽에 벽이 있으면
1 + 2 = 3이 그 셀의 값인 겁니다.
그래서 짠게 바로 이 코드.
cell[y][x] = Up ? 1 : 0 + Right ? 2 : 0 + Down ? 4 : 0 + Left ? 8 : 0;
프로그램은 오동작 했고 저는 도저히 그 원인을 찾아내지 못했습니다.
약 두시간의 삽질 끝에 문제를 해결했습니다.
cell[y][x] = (Up ? 1 : 0) + (Right ? 2 : 0) + (Down ? 4 : 0) + (Left ? 8 : 0);
OTL
이 바보.
Forums:
저도 최근에 같은
저도 최근에 같은 실수를 했습니다. :-)
- CN의 낙서장 / HanIRC:#CN
- 죠커's blog / HanIRC:#CN
연산자 우선 순위를
연산자 우선 순위를 잘 모르면 괄호부터 치는 편입니다. 괄호를 넣는 게 났습니까? 아니면 연산자 우선 순위를 찾아보면서 괄호를 최대한 줄이는 것이 낫습니까?
괄호를 넣으면 코드를 읽을 때 우선순위때문에 고민하지 않아도 되지 않나요?
..
컴퓨터에게는 줄이는것이 좋고 사람에게는 많은것이 좋습니다.
그리고 최적화 옵션 사용시 컴파일러가 다 알아서 합니다.
====================여기부터 식은어치====================
안녕하세요. 저는 야동 초등학교 2학년 6반 11번입니다!! 제 컴퓨터에 리눅스를 깔아보고 싶습니다. 리눅스라는건 어제 처음 들어 보았습니다.
리눅스에서도 카트라이더는 되겠지요? 설마 안되나요? 안되면 왜 쓰나요? =3=33 리눅스에서는 카트라이더 캐릭터 머리가 너무 커서 못받아들이나요?
연산자 순위를 잘
연산자 순위를 잘 모르는 정도가 아니라
그냥 맞다고 착각해버렸기 때문에 삽질을 한 겁니다. -_-;;;
왠만한 사람이
왠만한 사람이 아무리 최적화를 한다해도 컴파일러보다 못하다고 보시면됩니다.
그냥 보기에 편한방법으로 코딩하는게 최고입니다.
글쎄요.
일단 보기 편한방법으로 코딩하는 점에 대해서는 동의합니다.
하지만 여기서 최적화의 의미가 어떤 의미인지 모르겠지만,
compiler가 compile하여 생성한 assembly code와 사람이 직접짠
assembly code를 비교했을때 compiler의 최적화가 더 낳다고 하신다면 저는 아니라고 봅니다.
compiler의 성능이 얼마나 좋으냐에 달린 문제이겠지만.
아직까지는 숙련된 사람이 직접짠 assembly code가 compiler가 생성하는 assembly code보다
더 최적화 되어 있습니다.
run-time에 수집한 profile한 정보를 가지고 compile하였다해도 최적화의 여지는,
많지는 않겠지만 남아 있을거라는 생각이드네요.
말씀하신 요지가 assembly level이 아니라, c-code 상에서 사람이 어떻게 짜나
compiler가 알아서 잘해준다라는 것이였다면.
이것 역시 어느 정도는 맞지만 어느 정도는 아니라고 말씀드리고 싶네요.
분명 사람이 어떻게 c-code를 짜든 compiler가 최적화를 잘해주는것은 사실이지만,
compiler와 processor를 이해하고 c-code 매우 잘짜면 compiler가 더 최적화하기
쉽게 c-code를 작성할수 있습니다.
거의 compiler가 생성할 assembly code를 직접 짜는것 처럼 말이죠.
하지만 이정도까지 최적화를 해야된다면 차라리 assembly로 짜는게 낳을지도 모르겠네요.
일반인이 캐쉬까지
일반인이 캐쉬까지 고려해가면서 최적화를 한다는 것이 가능하다고 생각하지 않습니다. 어셈블리 언어를 안다는 것과 그것을 완벽에 가까울 정도로 최적화 하는 것은 다른 이야기라고 생각하기 때문에 C언어를 이용하는 것이 더 낫다고 생각합니다.
그리고 컴파일러와 프로세서를 이해하고 C 언어를 짜는 것은 C.A. 호어가 경계했던 성급한 일반화가 될 가능성이 매우 높지 않을까 우려가 되는군요.
- CN의 낙서장 / HanIRC:#CN
- 죠커's blog / HanIRC:#CN
많은 성능을
오늘 kldp가 이상하네요. 아래글이 제가 쓴글입니다.
많은 성능을
많은 성능을 요구하는 프로그램(os, codec, 3d등)에서 cache까지 고려하는 일은 일반적 일입니다.
심지어 고급 프로그래머의 경우 cache 뿐만아니라 branch prediction, data prefetch까지 고려해서 cycle 단위까지 생각하며 프로그램을 짜고 있기 때문에 processor architecture, compiler를 이해하면 일반인도 얼마든지 할수 있는 최적화 기술이 많이 있습니다.
물론 저 역시 assembly로 짜는것 보다 c 언어를 이용해서 짜는것이 portability 측면에서 훨씬 낳다고 생각합니다. 제가 이야기했던것은 정말 성능을 내야될 부분이 있을때 compiler가 생성하는 assembly 보다는 숙련된 프로그래머가 짜는 assembly가 더 최적화 될수 있다고 한것입니다.
compiler는 인간이 하기 귀찮은 일을 rule에 의해 기계적으로 수행하기 때문에 어떤 면에서는 사람보다 낳을수 있겠지만, 대부분의 경우 사람보다 낳지 않습니다.
제가 무식해서 그런지 모르겠는데 C.A. 호어가 누군지 모르겠네요. 그사람이 무슨말을 했는지도 모르겠고요. 그 사람이 무슨 말을 했건간에 저의 입으로 제 이야기를 드린다면 다음과 같습니다.
제가 compiler와 processor architecture를 이해해서 매우 잘짜면 compiler가 더 최적화 하기 쉽게 짤수 있다고 했는데, 실제로 그러하기 때문에 그렇게 이야기했습니다. 성능을 많이 요구하는 프로그램들은 실제로 그렇게 많이 하고 있고요. 몇가지 지금 생각나는 방법에 대해서 나열하자면...
- loop unroll을 하면 좀 더 빨리 수행될수 있겠죠. 물론 똑똑한 compiler는 알아서 잘해주겠지만 compiler는 의외로 똑똑하지 못해 자신의 rule에 딱 맞지 않으면 loop unroll을 해주지 않죠.
단점이라면 약간, 아주 약간 보기 싫은 code가 만들어지겠네요.
- loop coalescing을 하면 좀 더 빨라지겠네요. 단점이라면 특정 instruction을 지원하거나, 혹은 특정 기능을 지원하는 processor라면 제법 빨라지는 반면, 그런 processor가 아니라면 오히려 느려질수도 있겠네요.
- cache align, affinity는 너무 중요해서 말하지 않겠습니다.
- 한번에 수행하는 data type의 크기는 processor 마다, system 마다 틀리니 정말 쥐어짜야 한다면 이것도 고려하는게 좋겠죠.
- branch prediction은 code 중간 중간에 간단한 macro 하나 추가해서 compiler에게 hint를 줄수있기 때문에 고려하는게 좋겠죠. 단점이라면 아주 약간 보기 싫기도 하겠네요.
- data prefetch를 지원해주는 기계라면 적당히 잘 사용하면 효과를 많이 보겠네요.
- 기계의 종류에 따라 index 증/감후 비교시 zero를 비교하는게 빠른 기계가 있기도 하니 loop index 사용에서 add보다, sub가 더 낳은 기계가 있겠네요. (일반적으로 add와 sub의 cycle은 동일하나깐)
- data copy를 할때, bus의 mode에서 normal mode로 copy하는것 보다는 burst mode로 copy하는것이 빠르니깐 이것도 고려해서 data block의 크기와 한번에 복사하는 단위를 맞추어 주면 좋겠네요.
- function에서 parameter passing 할때 compiler 종류에 따라 parameter passing register의 개수가 정해지니, 이것도 고려를 해주면 좋겠네요.
- function 내부에서 사용하는 register까지 고려한다면 거의 assembly level에서 c code를 짜는것과 마찮가지 이기 때문에 논외로 치고, 단 register의 live-range를 보다 짧게 하면 spill될 register의 개수를 줄일수(architecture 공통) 있겠네요.
- data dependency, flow dependency를 고려하면 compiler가 보다 효율적으로 code를 생성하게 할수 있겠네요.
- simd, mimd를 지원하는 기계라면 이에대해 고려해주면 좋겠네요.(이건 compiler가 하기 힘든부분이군요.)
더 많이 있는데 이쯤하겠습니다. 이상과 같은 최적화 기법들이 c code상에서 어떤 영향을 미칠거라 생각하십니까? c code를 보기 힘들 정도로 readability를 떨어뜨릴거라 생각하십니까? 아니면 여러 기계에 이식하기 힘들게 할거라 생각하십니까?
전혀(사실은 매우 약간 그렇지만) 그렇지 않다라고 말씀드리고 싶네요.
그럼 어떤 의미에서 C.A. 호어씨가 compiler와 processor architecture를 이해해서 code를 짜는것이 성급한 일반화의 오류를 범한다고 했는지 말씀해주시겠습니까?
많은 사람들이 knuth가
많은 사람들이 knuth가 성급한 최적화는 만악의 근원이라고 불렀는데 퀵소트를 만든 C.A. 호어가 한 말입니다. 그 환경을 모두 이해하고 통제할 수 있다면 효과적이겠지만 일반적으로는 무리라고 생각했습니다. 대개 어셈블리 초보자들의 경우 컴파일러보다 더 비효율적인 코드를 만들어 내고 그것이 지엽적인 최적화 때문이라는데 동의하실 겁니다. 보통 사람들은 컴파일러를 믿고 프로파일링 후의 병목 부분만 해결하는 것이 가장 효과적일 것입니다. 하지만 anfl님이 캐쉬를 고려할뿐 아니라 다른 부분을 모두 고려하셔서 프로그래밍하신다니 매우 놀랍네요.
- CN의 낙서장 / HanIRC:#CN
- 죠커's blog / HanIRC:#CN
일단 그래서 저 역시
일단 그래서 저 역시 "숙련된 사람"이 짠 assembly code가 compiler가 생성한 assembly보다 더 낳다고 표현한것입니다.
숙련되지 않았다면 최적화 결과가 비슷하거나 혹은 더 나쁘기도 하겠지요.
그리고, assembly로 최적화 하는 부분은 대부분 assembly로 최적화기 적합한 부분들이기 때문에 global optimization의 영향을 크게 받지 않는 부분이라고 말해드리고 싶네요. function body가 무척 크거나, 혹은 vliw와 같은 architecture에서 무턱대로 assembly로 최적화 하는 일은 금해야겠지요.
때문에 양날의 검이라는 생각이드는군요. C.A. 호어씨 역시 "성급한 최적화"는 만악의 근원이라고 표현했다고 하셨는데, "성급한"이란 단어에 주목할 필요가 있다고 생각합니다. processor architecture, compiler를 충분히 이해하는 사람이라면 절대 "성급한" 최적화는 하지 않습니다. 딱 적당히 최적화를 하지요.
그리고 어설피 부분적으로 최적화하는것 보다는 system, architecture, algorithm level에서 최적화 하는게 더 낳겠지요.
인용:
"하지만 anfl님이 캐쉬를 고려할뿐 아니라 다른 부분을 모두 고려하셔서 프로그래밍하신다니 매우 놀랍네요."
제가 일하는 쪽에서 그 정도 최적화는 별로 놀랄일도 아닙니다. 항상 cycle 단위로 고민하기 때문에 최적화에 대해서 다소 민감한 편이죠.
그리고 주위를 둘러보아도 그 정도로 최적화 되어 있는 프로그램들은 얼마든지 있습니다. linux kernel, ffmpeg, mesa등등 다 그정도 최적화는 되어있습니다. 그중에서 특히 linux kernel이 architecture 최적화가 많이 되어 있다고 하겠네요. 제가 이전에 이야기한 최적화의 몇가지만 빼고 모두 linux kernel에 실제로 존재하는 것들입니다. 원하신다면 한번 확인해보시기 바랍니다.
일단 헷갈리면
일단 헷갈리면 찾아봅니다.
그리고 끄덕거린 후에 가장 보기에 편한 만큼만 괄호를 씁니다.
그래서 (컴파일러 입장에서) 필요 없는 괄호도 들어가긴 하지만
과다하게 쓰지는 않는 편입니다.(라고 믿고 있습니다. -_-;;)
이럴때는...
cell[y][x] = Up ? 1 : 0 + Right ? 2 : 0 + Down ? 4 : 0 + Left ? 8 : 0;
이렇게 가로로 놓아버리면 좀더 명확하지 않을까요? :-)
음... 보기에 좋으라고(나중에 분석을 위해서도...) 코드를 줄 맞춰서 놓다보면
간혹가다 나올 수 있는 실수죠. 저도 종종 경험하지만 저 같은 경우에는 일단 코드
시작부터 ';'로 끝나는 지점까지 코드를 작성한 후에 보기좋게 나열시키는 이중작업을
종종합니다. 습관이라면 습관이겠지만 가끔가다보면 그렇게 하는것이 삽질을 한번 더
줄일 수 있는 방법이 아닌가 생각해보기도 하죠.
------------------------------
좋은 하루 되세요.
------------------------------
좋은 하루 되세요.
저도 최대한 길게
저도 최대한 길게 두는데 동의합니다. 저는 항상 의미 단위로 몇줄을 쓰면 나중에 다시 고치게 되더군요.
- CN의 낙서장 / HanIRC:#CN
- 죠커's blog / HanIRC:#CN