소스를 최적화 해야 하는데 도움이 필요합니다.

lazycoder의 이미지

unsigned int dims_1[10], dims_2[10] 이 두 배열에 값을 초기화 하는 과정은 현재 이렇습니다.

for(i=0, j=1; i<10; i++, j++) {
    addr = getaddr(i);
    temp = addr << 8;
    temp |= addr;
    dims_1[i] = temp;
 
    addr = getaddr(j);
    temp = addr << 8;
    temp |= addr;
    dims_2[i] = temp;
}

질문은 소스 크기의 증가없이 성능, 메모리등에서 이득을 볼 수 있는 구조체와 초기화 함수를
어떻게 만들수 있는지 궁금합니다. 지금 상황은 이보다 더 작고 최적화된 소스를 짜야하는데 도움을 부탁드립니다.
꼭 구조체의 형태가 아니어도 괜찮습니다. dims_1, dims_2가 프로그램 전체에 사용되고 있는데
가독성이나 직관성, 사용 편의성등도 중요해서.. 요구사항이 많아서 죄송합니다. 도와주시면 감사하겠습니다.

* 추가.
이 소스는 어떤 제어장치에 임베디드되는 소프트웨어인데 그냥 마이컴 이라고 보시면 됩니다.
추가해야 할 함수들이 갑자기 늘어나는 바람에 메모리 부족으로 곤란을 겪고 있는데
보드를 재설계하고 바꿀수 없는 상황이라서 소프트웨어적으로 해결하려고 하는 중입니다.

그리고 저는 이쪽 분야의 개발자는 아니고 저도 해당 부서로부터 도움을 요청받아 제가 할 수 있는 만큼
최적화를 하였고 질문에 나온 소스는 그 결과의 일부입니다.

제가 잘은 모르지만 약간 설명을 드리자면
dims_1, dims_2 배열은 제어장치가 시작할때 ROM으로부터 데이터를 읽어와서 저장하는 변수입니다.
getaddr() 함수는 제가 손을 댈 수가 없습니다. 원래 함수명은 eeprom_read() 인가.. 그런데 getaddr() 함수는 제가
그 함수를 데코레이션한 것입니다.

앞서 말씀드렸다시피 제가 이쪽 분야도 아니고 업무도 잘 모르는 상태여서..
답변에 필요한 내용이 무엇인지 말씀해주시면 월요일에 담당자에게 물어보겠습니다. ;;

라스코니의 이미지

소스 상에서는 더 이상 최적화할 만한게 안보이네요.

더 해야 한다면 getaddr(i), getaddr(j)가 사실은 getaddr(0), getaddr(1) 이 됩니다.

getaddr() 이 어떤 type을 반환하는지 모르겠지만 getaddr(0), getaddr(1)를 한꺼번에 되돌릴 수 있다면 더 성능면에서 좋겠죠.

그리고 j 의 사용도 피하는 방법도 있겠네요. i를 사용해서도 되니까요.

lazycoder의 이미지

아.. 그러고보니 j는 없어도 되겠네요. 감사합니다.

grassman의 이미지

최적화라는 건 코드의 사용 조건을 정확히 알고 있는 상황에서 불필요한
부분을 제거하는 과정입니다. 위의 코드에서는 두 배열의 사용 조건을
전혀 명시하고 있지 않아서 최적화를 할 수 없습니다.

예를 들어 만약 dims_1과 dims_2 배열에 대해 초기화 이후 내용을 변경하지
않는다면 dims_1, dims_2 배열을 총 20개에서 11개로 줄일 수 있겠네요.

#define dims_1(x)       dims[(x)]
#define dims_2(x)       dims[(x) + 1]

초기화 할 때는

unsigned int dims[11];
 
for(i=0; i<11; i++) {
    addr = getaddr(i);
    temp = addr << 8;
    temp |= addr;
    dims[i] = temp;
}

사용할 때는 dims_1[x], dims_2[x]를 각각 dims_1(x), dims_2(x)로
치환하면 됩니다.

lazycoder의 이미지

dims_1, dims_2는 소스 전반에 걸쳐서 read되고 write도 일어나는것 같습니다. (뭐때문에 write를 하는지 모르겠고 디버깅을 통해서 확인..)
이 배열들의 첨자의 위치들은 문맥에따라 각각 어떤 상수적인 의미를 지니는듯 했습니다.
#define을 사용하기 보다는 typedef나 struct를 쓰면 어떨까 싶은데
제가 C언어가 주력언어도 아니고 이런 극한(?)의 조건에서 프로그래밍을 한 적이 없다보니
그렇게해서 얻게되는 이득이 있는지 없는지를 잘 모르겠습니다.
수행속도나 사용 메모리의 감소는 없다하질라도 소스의 크기에 영향을 주지않으면서 가독성이라도 좋아졌으면 좋겠는데
가독성만 좋아지고 정작 중요한 메모리 사용이 늘어나면 곤란해져서 말이죠.. 참 어렵네요. ;;

shint의 이미지

어떤 경우는.
for문안에 함수를 여러개 두는것보다
for문을 여러개 만들고 함수를 각각 두는것이 더 빠른 결과를 내는것으로 알고 있습니다.

이런식보다.
for(;;)
{
Fn_test();
Fn_test();
}

이런식으로 만들으면 빠르다고 알고 있습니다.
for(;;)
{
Fn_test();
}
for(;;)
{
Fn_test();
}

믿거나 말거나.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

lazycoder의 이미지

한번 적용 해보겠습니다. 이런 팁이 있으면 더 좀 가르쳐주세요. ;;

sunyzero의 이미지

원글에서 loop fusion을 거꾸로 설정했습니다.(어떻게 보면 loop unrolling같기도 하지만...내부 코드가 같은 코드를 반복시킨 것인지 의미가 좀 헷갈리는군요. 서로 다른 함수를 오타친것 같기도 하고...)

하지만 loop 최적화는 컴파일시에 -Os급(size를 늘리지 않는 최적화) 이상이면 알아서 컴파일러가 최적화 해줍니다.

물론 소스코드가 복잡하여 컴파일러가 알아서 최적화 하기 힘들수도 있으므로 간결하게
짜주는 것이 필요합니다.(길이의 의미가 아니라 내부계산에서 상호참조라든지 분기문 같은게 없어야 됩니다)

이렇게만 해주면 최적화 옵션으로 컴파일시 loop unrolling, loop fusion, loop vectorization, loop peeling등은 알아서 적용됩니다.
========================================
* 부분이 전체를 대변하는 하나의 속성일때 진리이다.
영속적이지 못한 것은 전체가 될 수 없다.

========================================
* The truth will set you free.

prio의 이미지

gcc 4.3 기준으로

loop-unrolling은 사용자가 지정해줘야 하며,

loop vectorization은 -O3 에서 켜집니다. 이 때 loop peeling도 함께 enable되구요.
(참고로 gcc의 auto-vectorization은 4.3 이상에서 추가 되었습니다.)

loop fusion을 하는지는 모르겠네요. 아마 지원하지 않는 것으로 알고 있습니다.

sunyzero의 이미지

댓글을 보고, 매뉴얼 페이지를 보니 좀 많이 다르군요.
지금 4.4 매뉴얼을 보는데, 제기억에 예전에는 loop-optimize던가 optimize-loops던가하는 옵션이 있었던 것 같은데 사라졌나 봅니다. 안보이는군요.

loop-unrolling은 -O#에서 켜지지 않는게 맞고, loop vectorization도 O3나 되어야 켜지는군요.
원글에서 오브젝트 사이즈에 민감하다고 하니 loop관련 최적화는 거의 못쓸것같아 보입니다.
========================================
* 부분이 전체를 대변하는 하나의 속성일때 진리이다.
영속적이지 못한 것은 전체가 될 수 없다.

========================================
* The truth will set you free.

shint의 이미지

이런게 있었군요. ㅋㅋ 전 몰랐슴.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

M.W.Park의 이미지

loop unrolling에 관한 거라면 설명이 반대가 되어야하는거 아닌가요?
-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂

-----
오늘 의 취미는 끝없는, 끝없는 인내다. 1973 法頂

greenufo의 이미지

addr = getaddr(0);
for(i = 0; i < 10; i++) {
    dims_1[i] = (addr << 8) | addr;
    addr = getaddr(i+1);
    dims_2[i] = (addr << 8) | addr;
}

이렇게 해보시면,

j 변수와 temp변수가 필요없게되며, 해당 변수가 쓰이던 연산이 줄어들고,
getaddr()함수를 call하는 횟수가 20번에서 11번으로 줄어들것 같습니다.

lazycoder의 이미지

이런 트릭도 있군여. 감사, 감사합니다.

댓글 달기

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