최적화 관련 질문

vani2의 이미지


C++11 기준으로 답변해주시면 감사하겠습니다.

이전에 어느 정도 시간이 지난 문서를 보았는데 최신문서를 찾기어려워서 질문해 봅니다.

1. 함수의 인수를 4개 이하로 하면 속도에 유리하다고 본 것 같은데.. 사실인가요?

2. 일정 크기가 넘지 않는다면 구조체를 인수로 넘길때 레퍼런스를 사용하디 않아도 copy elision 기능이 작동하여 최적화된다고 본 것 같은데 그 구조체의 기준 크기는 어느 정도 인가요? 아니면 이것이 컴파일러나 시스템에 따라 다를 수 있나요?

3. 배열 첨자에는 복잡한 연산을 하지않는 것이 좋나요?

4. 구조체 복사시에 memcopy 나 std::copy 를 사용하라는데 그렇게 하는것이 속도 향상에 도움이 되나요?

5. const와 #define은 성능면에서 차이가 있나요?

매우 뉴비라서 이것저것 찾아보았는데 약간의 잉여력이 발동하네요..

effective c++은 구매 예정입니다...

mirheekl의 이미지

1. 4개뿐만이 아니고 적을수록 좋습니다. 스택작업이 줄어드니까. 물론 콜링 컨벤션과 플랫폼에 따라 최초 몇개의 파라미터를 레지스터에 저장해서 빠른 속도를 얻는 경우도 있고 이경우에는 당연히 그 한계 이하로 유지해주면 큰 도움이 되겠죠. 4개란건 아마 여기서 나온 숫자가 아닐까 합니다.
2. 아무리 작다 해도 그렇게 하면 함수 내부에서 오브젝트를 변경했을 때 바깥에도 적용이 돼서 프로그램이 오동작하게 됩니다. 혹시 함수내 오브젝트 변경 가능성 여부를 판독해서 최적화할진 모르겠지만, 만약 그런 기법이 있다면 환경에 따라 당연히 기준과 방법이 달라지겠지요.
3. 패스... 질문의 요지를 모르겠습니다. 어차피 복잡한 계산을 하더라도 미리 인덱스 계산이 끝난 뒤에 해당 배열에 접근하기 때문에 차이점을 잘 모르겠네요. 물론 연산을 아예 안쓰고 상수로 처리하면 더 최적화가 되겠지만요.
4. 생성자 소멸자등을 죄다 패스해버리므로 도움이 되겠지만 구조체라고 그런걸 쓰지 말란 법은 없으니 권장하고 싶지는 않네요. C에서 넘어온 구조체거나 오브젝트의 특성에 대해 확신하고 있다면 괜찮을듯 합니다.
5. 일단 제가 테스트해본 바로는 소스 파일 하나에서는 차이가 없습니다. 그런데 소스나 모듈이 여러개일 경우 다른 방식으로 컴파일될 확률이 있습니다. 특히 메모리 사용량이 달라지지 않을까 생각되는데.. 이건 테스트해보면 금방 나오겠지만 해보기가 귀찮네요. 메모리 사용량 차이가 있다면 성능 차이가 있다고 말할 수 있겠죠.

--

vani2의 이미지

아하...

모두 플랫폼마다 달라지는군요.

답변 감사합니다.

많은 도움이 돠었습니다

jick의 이미지

(by Donald Knuth)

질문하신 것들은 (99%의 확률로) 프로그램의 성능에 눈에 띌 만큼 영향이 없거나 컴파일러 종류/버전/옵션에 따라 언제든지 달라질 수 있는 내용입니다.

정말로 이런 선택이 어떤 영향을 주는지 (예를 들어 함수 인자를 여섯 개에서 네 개로 줄이면 성능이 몇 % 빨라지느냐) 알고 싶다면 같은 일을 하는 프로그램을 그렇게 두 가지 버전으로 짜서 속도를 비교해 보는 수밖에 없습니다.

그리고 결과가 나온다 해도 *그 프로그램을* *그렇게 돌리면* 그런 속도차이가 난다는 거지 일반화할 수 있는 내용이 아닙니다.

다시 말씀드리자면 구체적인 프로그램과 구체적으로 그 프로그램을 돌리는 상황이 주어지지 않은 상태에서 이런 질문을 하는 건 무의미합니다.

vani2의 이미지

아 환경마다 달라질 수 있는 것이군요..

다음부터 환경을 명시하겠습니다.

답변 감사합니다

라스코니의 이미지

1. 함수의 인수를 4개 이하로 하면 속도에 유리하다고 본 것 같은데.. 사실인가요?

>>> 인수가 적으면 적을수록 함수 호출시 수행되는 스택 확보 code 가 줄어드니 빨라지기는 할 테지만 그렇다고 인수를 줄일수는 없으니 무용 지물...

2. 일정 크기가 넘지 않는다면 구조체를 인수로 넘길때 레퍼런스를 사용하디 않아도 copy elision 기능이 작동하여 최적화된다고 본 것 같은데 그 구조체의 기준 크기는 어느 정도 인가요? 아니면 이것이 컴파일러나 시스템에 따라 다를 수 있나요?

>>> 구조체를 넘기는 것 자체가 엄청난 오버 헤드를 줍니다. 어떤 것을 사용해서 복사가 되어야 하니...

3. 배열 첨자에는 복잡한 연산을 하지않는 것이 좋나요?

>>> 첨자 연산에 따라서 cache miss가 일어날 수 있다면 속도면에서 많이 불리하겠죠.

4. 구조체 복사시에 memcopy 나 std::copy 를 사용하라는데 그렇게 하는것이 속도 향상에 도움이 되나요?

>>> 엄청나게 복사를 많이하는 작업을 하지 않는다면 거의 무시해도 될 겁니다.

5. const와 #define은 성능면에서 차이가 있나요?

>>> 몇 바이트 메모리를 아끼는 것 외에는 아무 차이도 없을 것이고...

코드는 cache hit/cache miss 상황을 고려하는 경우 외에는 그냥 짜도 됩니다.
임베디드 할게 아니면 코드 최적화는 생각할 필요가 없음.

vani2의 이미지

아하..

이해가 잘 되었습니다.

구체적인 답변 감사합니다.

cinsk의 이미지

1. 인자 갯수가 속도에 미치는 영향은
함수 호출에 인자를 전달하는 방식에 따라 결정될 것이고,

CPU에 따라 달라질 수 있으며 (예: x86, x86-64, etc.)
OS에 따라 달라질 수 있습니다. (정확하게, 해당 architecture에서 사용하는 ABI에 따라..)

Linux, Mac 등 계열은 System V Application Binary Interface를 보시면 됩니다.

물론 언어에 따라서 (C/C++) 달라질 수도 있지만, 큰 차이는 없을 겁니다.

C++11 기준으로 말한다면, 인자 갯수에 따른 속도 영향은 implementation에 따라 다르다가 정답일 듯.

참고로 Linux 64bit에서는 첫 6개 정수형 인자와 첫 8개 실수형 인자는 stack이 아닌 register로 전달됩니다.

2. copy elision이 되는 것과 object 크기와는 별 상관이 없습니다.

copy elision은, 특정 상황 (예 object가 return value로 쓰일 때)에서
불필요한 복사가 안되게 하는 것이기 때문입니다.

크기와 상관있는 것은, 함수 인자로 오브젝트가 직접 (reference나 pointer 없이) 들어왔을때,
ABI에 따라 이를 (1) stack에 넣을 것인지 아니면 (2) 다른 메모리에 복사해서 stack에는 pointer만
들어갈지가 결정됩니다. (이는 POD type에 대해 유효)

참고로 64bit linux에서 POD type의 크기가 16 byte이하이면 stack에 들어갑니다.

3. 당연히 복잡한 것보다 간단한 것이 빠르고 이해하기 쉽겠죠.

4. POD type인 경우 당연히 memcpy가 빠릅니다. memcpy는 일반적으로 라이브러리 또는 컴파일러에서
최적화가 잘 되어 있습니다.

5. 일반적으로 preprocessor macro가 제한적이며, 미묘한 차이가 있을 수 있지만, 무시할 수준일 겁니다.

vani2의 이미지

와..

정말 자세한 설명 감사드립니다.

매우 많은 도움이 되었습니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.