포인터 참조레벨과 속도

macros의 이미지

list[x[5]].value->x->z 와 같이 참조 레벨이 다소 깊은 int 변수가 있다고 했을 때,

int *p = list[x[5]].value->x->z; 포인터 변수를 할당 하는것과

list[x[5]].value->x->z 를 직접 사용하는 것 중

어떤게 속도에서 잇점을 가질 수 있을까요?

단, 코드 가독성에서의 잇점은 배제합니다.

klutzy의 이미지

이렇게 생각해보세요.

x = a + b + c + d;라는 문장이 있다면 먼저 a+b를 계산한 다음, 거기에 c를 더한 값을 계산한 다음, 마지막으로 d를 더해서 x에 대입해야 합니다.

a+b를 계산한 값은 어디에 저장해야 할까요? c를 더한 값은?

결국 컴파일러는 코드를 풀어놓는 작업을 해야 합니다.

tmp1 = a + b;
tmp2 = tmp1 + c;
x = tmp2 + d;

jick의 이미지

C에서는 포인터라는 놈 때문에 어느 변수/함수가 어느 주소를 건드릴지 컴파일러가 미리 알기 힘듭니다. 그래서 동작이 달라지면 안되니까 최적화를 보수적으로 할 수밖에 없습니다. 예를 들어

int *p, *q;
p = list[x[5]].value->x->z;
f(); /* Doesn't update list */
q = list[x[5]].value->x->z;

이 경우 사람은 f에서 포인터가 바뀌지 않으니 마지막 줄을 q = p로 바꿀 수 있다는 걸 알아도, 컴파일러가 이를 알기는 매우 어렵습니다. 그래서 이런 경우에는 미리 대입해놓고 쓰면 도움이 됩니다.

하지만 최적화란 게 그렇듯이 컴파일러의 똑똑함에 따라 결과가 어떻게 달라질지 모르므로 직접 짜서 벤치마크를 돌려보는 게 가장 확실합니다.

inhosens의 이미지

list[x[5]].value->x->z 가 int * 라는 의미 같습니다.
다른 분들이 설명해 주셨지만 이 경우 컴파일러가 전혀 최적화해주지 않는 다는 가정을 하면
이 값을 사용할 때마다

x의 값 read
x[5]값 read
list의 값 read
list[x[5]].value의 값 read
list[x[5]].value->x 값 read
list[x[5]].value->x->z 값 read

위와 같은 절차를 밟아서 int * 값을 얻게 됩니다.
int *p = list[x[5]].value->x->z;
는 write 한번 하는 것으로 지속적으로 사용되는 위의 6번의 read를 1번의 read로 대체하는 역할을 합니다.

실제적으로 compiler가 많은 부분을 최적화 해주는데 간혹 안되는 부분들이 있어서 그냥 습관적으로 눈에 보이는
부분은 손으로 직접 대체해버립니다.

송지석의 이미지

일반적으로 포인터로 할당하는 게 더 좋다고 보이네요.
매번 인덱스를 보게 되면 메모리 로드 연산을 자주하게 됩니다.
포인터로 쓰면 레지스터에서 처리가 가능한 경우가 많죠.
rommance.net

papirus76의 이미지

포인터 연산을 아직 잘 이해못하고 계신듯한데요.
list[x[5]].value->x->z 같은경우 포인터 디레퍼런스 연산이 4번 일어나죠.
디레퍼런스하는 속도는 대부분의 기계에서 메모리 참조 연산이기 때문에 굉장히 느린편에 속합니다
대부분의 컴파일러가 이런부분에서 최적화를 기대하긴 힘들다고 보구요~~. 최적화 된다고 해도 속도를 고려한다면, 좋지못한 방법이고, 가독성도 좋지 못합니다.

list[x[5]].value->x->z 의 주소를 0x1000 이라고 가정하면
전자의 경우 int *p = 0x1000 ; 형태가 되어서 참조시에 *p 형태의 디레퍼런스 연산이 딱한번만 일어나기때문에 , 속도/가독성면에서 월등이 이득입니다.
대신에 스택에 포인터 자료형 크기만큼 메모리를 잡아 먹겠죠(32비트에선 달랑 4바이트, 것도 동적사용임으로 메모리를 쓴다고 보기힘들죠)

댓글 달기

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