성능측면에서 볼때 긴 하나의 함수가 나을까요? 여러개의 모듈로 나누어서 호출하는 함수가 나을까요??

baboda4u의 이미지

여러 글들을 읽어 보면서 느끼는 점입니다.

물론 함수가 길어 지면 보는 사람 입장에서는 답답할뿐이고 손대기도 싫을뿐이죠...

그래서 함수가 길어 지면 모듈로 나누는 것으로 알고 있습니다.

하지만...성능을 중요시 하는 프로젝트인 경우!! 어떻게 하는 것이 좋을까요?

함수 하나 더 호출하는 비용 vs 가독성...매번 작업할때 마다 고민이 됩니다.

그래서 매크로 함수를 이용하기도 하는데요 그것도 한계가 있고...여러분들은 어떻신지요???

Hyun의 이미지

함수로 나누면 코더가 편해서 알고리즘의 성능이 올라갑니다.
그리고, 대개의 경우 함수로 나눈다고 해서 컴파일러가 그것을 실제로 함수로 만들지는 장담 못합니다.


나도 세벌식을 씁니다
rdy0706의 이미지

성능을 중요시 한다면 당연 성능을 중요시해서 작성을 하는게 옳다고 생각이드네요.

함수 호출에도 어떤 방식이냐에 따라서 성능을 오히려 저하시킬수도 있습니다.

또한 함수가 깊어지면 오히려 가독성이 떨어질 수도 있구요!!

적절하게 설계하는것이 설계자의 능력이라고 생각이 듭니다!!^^

Fe.head의 이미지

인라인 함수로 나누면 되지 않을까요?

-----------------------
과거를 알고 싶거든 오늘의 네 모습을 보아라. 그것이 과거의 너니라.
그리고 내일을 알고 싶으냐?
그러면 오늘의 너를 보아라. 그것이 바로 미래의 너니라.

고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"

cleol의 이미지

특수한 환경(매우 열악한 임베디드 기기라던지 등등) 이 아니라고 가정하면

"함수 하나 더 호출하는 비용" 은 아무 의미 없습니다. 그런 거 신경쓸 필요 전혀 없습니다.
실제로 대부분의 경우, 성능에 영향을 미치지 않으니까요.
정말 정말 많이 호출되서 병목 지점으로 작용하는 것이 분명한 경우에만 "함수 하나 더 호출하는 비용"을 신경쓰면 됩니다.
"아름다운 디자인"에 더 신경쓰시는 것이 좋습니다.

sangheon의 이미지

속도가 문제가 되면 프로파일링 해서 병목 지점에 대해 튜닝 작업을 합니다.

--

B/o/o/k/w/o/r/m/

--

Minimalist Programmer

sangwoo의 이미지

Micro-optimization은 장기적으로 볼때 성능 향상에 큰 도움이 되지 않는다는 글을 본 것 같군요.
----
Let's shut up and code.

----
Let's shut up and code.

chadr의 이미지

최적화는 컴파일러에게.. 코드는 사람이 보기 쉽게..

이렇게 하시는게 좋습니다.:)
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

나빌레라의 이미지

C로 코드를 작성한 다음 컴파일해서 역어셈블 해보면 아시겠지만,

함수로 만든다고 컴파일러가 그걸 100% 전부도 서브 프로시저 콜로 번역해주지 않습니다.

그리고 서브 프로시저 콜을 한다고 해서 그게 그렇게 엄청나게 시스템에 성능 저하를 주지도 않습니다.

단지 레지스터 몇개를 메모리에 백업하고 리스토어 하는 비용만 들 뿐이지요.

그정도 비용조차도 크리티컬하게 처리해야 하는 프로그램이라면

당연히 함수로 안갈라질 수록 성능이 좋긴 하지만, baboda4u 님께서 작성하는 프로그램이

과연 그정도까지의 최적화를 요구하는지 진지하게 고민해 보세요.

경험상 느끼는 거지만 고급언어 코드는 가독성이 제일 중요한것이더라구요.

(한 3개월 후에 코드를 작성한 본인도 못알아 봐서 디버깅이 불가능해지는 사태가 발생하기도 합니다.)

----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

----------------------
얇은 사 하이얀 고깔은 고이 접어서 나빌레라

anfl의 이미지

가독성을 버리지는 마세요. 그건 바보같은 짓입니다.

성능에 매우 민감하다면 inline function으로 처리하시던지
-finline-functions 옵션으로 컴파일시 inline하시던지 하십시요.
아니면 dynamic profiler 기반의 최적화를 수행하시던지,
-fomit-frame-pointer옵션으로 leaf function들에 대해서
function frame pointer를 제거하거나,
caller saved register의 spill 코드를 제거할수도 있습니다.

잘 모르기 때문에 한가지 방법 밖에 안보이는 겁니다.
가독성과 성능 두가지 다 만족할수 있는 방법에는 여러가지가 있습니다.


hultul의 이미지

주체가 누구(프로그래머 또는 컴파일러)인가에 상관없이, 과도한 inlining은 Compiler 입장에서 register pressure를 증가시킵니다.
즉, 동시 사용 변수가 너무 많아지면서 physical register에 할당되는 확률이 떨어지므로, 성능 저하로 이어질 수 있습니다.
__
코더에서 프로그래머까지

코더에서 프로그래머까지

anfl의 이미지

많이 그렇습니다.
때문에 -O3가 -O2 보다 성능이 떨어지는 경우가 자주 발생합니다.
제가 위와 같이 말한것은 '적합하게' 사용한다는 전제에서 말한것입니다.

애초에 코드상에서 variable의 live range를 최대한 짧게 작성하면
spill이 발생할 수 있는 부분을 많이 줄일수 있습니다.
물론 그럴수 없는 부분도 분명 존재하죠.
그러한 부분은 상황에 맞게 잘 대처한다면 되지 않을까 쉽네요.

말씀하신 '과도한' inline이 아니라 '적합한' inline을 말한 것이라 보면 될것 같습니다.


baboda4u의 이미지

많은 의견 감사합니다. ^^

(_ _)

============================
Stay Hungry, Stay Foolish

jinhoy97의 이미지

Inter Procedure Optimization 이란 최적화 방법을 쓰면 내부에서 다 한 함수로 합쳐줍니다. 비록 Intel Compiler만 지원하는 방법이지만요... 즉 컴파일러만 좋은거 쓰면 해결될 고민입니다. 이런 고민은 요즘은 덜 할만 하지요.

blee의 이미지

파이프라인 유지, 캐쉬 효율성을 본다면, 분기를 되도록 안하는 것이 좋겠지만, 얼마만큼의 성능을 가진 환경인가에 따라서 고려 대상이 안될 수도 있고, 될 수도 있다라고 생각합니다. 예를 들면, 임베디드 환경이면 고려 해야 할것이고, 서버급이면 안해도 된다. 라는 것일까요? 예를들자면^^

nineye의 이미지

저는 임베디드 환경에서 개발하고 또한 한번 실행 시, 수초이상 걸리는 엔진을 개발하기 때문에 성능에 상당히 많이 신경을 쓰는 편입니다.
일단은 완전히 성능 위주로 보신다면 c나 어셈으로 구현하셔야 할 것 같습니다. 왜냐면 c++은 보이지 않는 부하(상속, this call, dynamic binding 등등)가 많고, 어셈은 논리적으로는 여러 개의 instruction이 필요할 것 같은 연산도 한 instruction에 처리할 수 있는 operation code들이 많기 때문이죠. 물론 이것은 컴파일러가 최적화 하지 못하는 코드에 한해서 입니다.
그리고 위에 분들이 말씀하셨듯이 시스템에 따라 cpu cache hit율을 고려해서 inline을 적절히(?) 쓰셔야 할 것 같습니다.
또한 class로 디자인 하신다면, 또 고려해야 할 여러 가지 요소들이 있습니다. 예를 들면, 스택 영역을 사용할 때, member로 미리 스택 영역에 할당해서 다른 멤버 함수들이 재할당없이 해당 멤버 변수를 접근하게 할 것인지, 아니면 cpu cache hit를 고려해서 member가 아닌, 실제 변수를 사용하는 곳에서 스택 영역에 할당함으로써 사용을 할 것인지... 등 플랫폼, os에 따라 결정해야 할 내용들이 많을 것입니다.

저의 경우, 임베디드 환경에서도 개발하긴 하지만, 동일 프로젝트를 wince, linux, windows(pc) 등등 여러 플랫폼에서 지원해야 하고, 다양한 서비스에도 적용할 수 있어야 하기 때문에, 구조적 프로그래밍쪽으로도 좀 치우쳤다고 할 수 있을 것 같습니다.
결국 선택한 모습은 policy based template metaprogramming 이었습니다.

_________________________________________________________

nineye's blog

죠커의 이미지

호출에 의한 부하보다 bottleneck이 더 중요한게 아닐까요?

대게의 경우엔 깔끔하게 짜고 프로파일링을 하시는 게 나을 것 같습니다.

- 죠커's blog / HanIRC:#CN

sjg0120의 이미지

캐쉬의 종류에는 Instruction Cache와 Data Cache가 있습니다.
함수를 인라인해서 사용하면 Jump Instruction은 줄게 되겠지만 Instruction Cache를 오염시키게 됩니다.
따라서 오히려 성능 저하를 시킬 수가 있죠... 아시는 내용이겠지만 인라인 할 함수의 길이가 길다면
성능을 저하시키게 됩니다. 또한 최근 나오는 컴파일러와 CPU의 Branch Prediction 성능이 좋기때문에 Jump 로 인한
비용도 적습니다. 결론은 프로파일러 돌려서 상황에 맞게 사용해서 쓰셔야겠군요
Ulrich Drepper의 What every programmer should know about memory를 한번 보시기를 권장해 드립니다.^^

hongminhee의 이미지

인라인 함수를 쓰시면 됩니다.

mach의 이미지

함수 없애고, calling sequence 및 return sequence를 줄여서, 약간의 성능을 얻을 수 있을 것입니다만,
플랫폼의 컴퓨팅파워가 좋다면(서버급?), 버리는것(가독성, 유지보수등)에 비해 상당히 미약한 효과만을 얻으리라 예측됩니다. 궁극적으로 손해일지도...
선택의 여지가 없어서, 극소 메모리도 아껴야 하는 상황 등이라면, 당연히 그렇게 해야 겠지요.
그러나, 이러한 함수 수준 호출 오버헤드 고려라면, 티끌모아 태산이라지만, 아무리 튜닝해도 수십퍼센트(수십이란것도, 과거 코드가 엉망인 경우)이상 좋아지기는 힘들기 마련입니다.

섬세한 프로그램인 경우에는 프로파일러등으로, 병목지점을 찾아내고, 병렬성을 찾아내어, 튜닝(H/W, S/W) 및 컨커런트 모델링해서 풀어야 할 것입니다.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

bungker의 이미지

어떤분한테 본인이 짠 결과물을 보여달라고 해서 소스를 본적이 있습니다.
함수하나가 1000라인이 넘어가더군요. 변수는 a,b,c 이런식이고요..
왜 이렇게 하느냐고 물어보니 이 프로그램은 속도를 중시하기 때문에 그렇게 짠다고 하더라구요.
엔지니어적 마인드는 좋은데.. 솔직히 신입으로 뽑기는 그랬습니다.

antaran의 이미지

개발자로서 변수 a, b, c에 대한 것은 그 어떤 변명의 여지도 없으리라 생각됩니다.

학교에서 숙제를 해서 낼 때도 a, b, c로 네이밍 하는 것은 좀 점수 깎일 듯 한데... -_-;;;

mandami의 이미지

혹시 함수 콜 비용이 얼마나될까, 싶어서 측정해봤는데
다른 Instruction과 비교해도 턱없이 작더군요.

게다가 컴파일러가 최적화까지 해주니 그냥 무시하는게 맞는거 같습니다.

성능을 위해 1천줄짜리 소스 짜는건 성능상 0.01%의 이득을 위해 너무 많은 것을 포기하는거 같습니다.