속도향상과 일반 배열 할당과 동적 메모리 할당 시 한계 관련 질문 드립니다.

kknd345의 이미지

속도향상과 일반 배열 할당과 동적 메모리 할당 시 한계 관련 질문 드립니다.

기존 프로그램은 동적 메모리 할당이 매우 빈번히 일어나는데

그 동적 메모리 할당 하는게 오버헤드가 크다는 것을 들었습니다.

그래서 동적 메모리 할당을 없애고 시작후에 최대 크기의 배열을 선언한 후에

사용할 생각입니다.


제가 아는 배열 할당 하는 방법은

1.

int a[][][];

2.

int* a = new int[][][];

2가지가 있는데 지금 짜려는 프로그램은 제법 큰 크기의 3차원 배열을 필요로 합니다.

( 100MB 정도는 안될거 같은데 혹시 확장성을 고려하면 200-400 MB 정도는 커버 가능 해야 할듯 합니다. )

그래서 질문이 위 2가지 방식에 메모리 할당에 한계가 있다고 들었는데 그게 어느정도 수준입니까?

혹시 두 방법다 큰 배열을 할당 할수 없다면 다른 방법이 있나요?

그리고 과연 이방식이 속도를 증가 시키는데 도움이 될까요?

그리고 추가적으로 프로그램 실행 속도를 올리고 싶을때 참고해야 되는 책이나 자료 사이트 있으면 소개좀 부탁드립니다.

JuEUS-U의 이미지

제가 알기로는 그 배열이 지역변수만 아니면 문제는 없습니다.
저는 200MB까지 써봤습니다.
다만 그건 C에서 1차원 배열이였습죠 = _=
C++은 혹시나 다를지도 모릅니다....

sio4의 이미지

예전에 제 코드와 함께 협업관계에 있던 다른 팀원의 코덱 라이브러리를 프로파일링한 적이 있는데, 라이브러리 부분에서 CPU를 가장 많이 잡아먹는 코드는 "메모리 재할당" 부분이었습니다. 제 코드에서의 병목은 "너무 직선적으로 작성한 알고리즘"이었고요.

개선이라는 것은 역시, 개선할 "꺼리"를 먼저 찾는 것 부터 시작하시는 것이 맞을 것 같습니다.

또 다른 프로젝트에서 성능문제로 고민하면서 시도했던 것은 MMX/SIMD 활용이었습니다. 특히, 개량된 memcpy 함수를 사용하여 성능향상을 꽤나 보았던 기억이 납니다. (물론 메모리 카피가 매우 빈번하게 일어나는 형태의 프로그램이었으니까 그랬던 것이고요)

IA32에서 작업을 했었는데, 생각치도 못했던 인텔의 기술문서와 AMD의 기술문서가 직간접적으로 도움이 되었었습니다.

--
"The love you take is equal to the love you make." The End, by Beatles

--
"The love you take is equal to the love you make." The End, by Beatles

kalstein의 이미지

C++의 경우는 동적할당이 기본적으로 많죠. 그래서 매우 빈번할 경우 성능에 문제가 있게됩니다.
(보통 new operation 한번에 500사이클 이상이 먹는걸로 알고있어요...)

해결책으로 나온것이 custom new operator 들이구요, linux커널쪽도 마찬가지 문제로 인해서...
page 단위로 할당/해제되는 slab allocator가 있습니다. (현재는 slub 을 쓴다더군요)
그걸 커널단에서 user app library로 끌고온 libumem 이란것도 있구요.

일단 알고리즘적으로 빠르게 만드시구요 (검색 알고리즘을 버블소트 -> 퀵소트로 바꾼다던가)
아키텍쳐를 제대로 세우고 하면...동적 할당 자체는 빈번해도 괜찮을 것 같습니다.

큰 메모리를 잡고, 거기에 뭔가 프로세싱하는 스타일이 보통 C 스타일이죠...
이럴경우, 해당 메모리변수에 묶이는 function들이 많아지게 되므로, 코드의 dependency가 증가하고,
유지보수가 어렵습니다.

뭐 간단히 테스트 하시는거라면 상관없지만요 ^^

------------------------------------------
Let`s Smart Move!!
http://kalstein.tistory.com/


------------------------------------------
Let`s Smart Move!!
http://kalstein.tistory.com/

rubenz의 이미지

AIX 에서 500MB 까지 해보았습니다.
단순히, 배령. char p[1024*1204*500] 으로요..물론 64비트겠지요?
메모리를 할당하고 사용하는데, CPU의 원칙이 있습니다.
1) 인접한 메모리 사용은 빠르다.
2) 자주 쓰는 메모리는 빠르게 접근한다.
고전적인 방법입니다만, if ~else 를 쓰는 것보다.
while 문 안에 swith(nstate) 식으로 써서 loop를 돌리는게 더 빠르다는 전설이..ㅋ(윈도우 프로시저가 모두 이런 식으로 되어 있지요..)
특히, 유닉스 쪽이라면, 제가 자세히 성능 실헝은 해보지 않았습니다만, 대규모 파싱, 예를 들어, 10GB 짜리 파일 파싱등을 수행할때, 확연히 차이가 나는것 같았습니다.(if ~else 보다는 상태 변환에 의한 while 문)
한번에 500MB 읽고 파싱한 후에 수정해서 저장..10G가면 20번 읽고/써야 겠지요?
그런데, 같은 64Bit라도 같은 같은 AIX라도 대규모 배열을 로컬(전역도 마찬가지)에 선언하고 그 함수에 들어갈때(혹은 전역 변수에 접근할때), 어떤 Box는 500MB도 되고 어떤 Box는 100MB도 안되고 50MB까지만 되고 그렇습니다.(Core에 세크먼트 결함하면서 죽습니다.) 그 이유는 모릅니다.ㅡ.ㅡ
(참고로 저는 500MB변수를 전역으로 선언하고 사용했고, 쓰기 전에 초기화 하고 쓰고 그랬습니다. )
아..그리고, 제 경험상으로는 동적 배열을 하든, 그냥 배열 선은 하든지 한계는 비슷하더군요.

sblade의 이미지

C 에서 메모리 할당엔 3가지가 있는데 static 할당, stack 할당 (automatic 할당), 그리고 dynamic 할당입니다.

int a[];
static int b[] = {};
int* c = new int[]; // or malloc() in C.

하면 a 는 stack, b는 static, c 는 dynamic 입니다.
stack 은 일반적으로 몇 메가 내외의 크기이며 (리눅스면 보통 8메가입니다.), a 가 그 크기를 넘어가게 되면 segmentation fault 를 일으킵니다. 최대 크기가 조절가능하긴 한데, 권장되는 방법은 아닙니다.
static 할당을 하면 data segment (정확히 말하면, 사용자에 의해 초기화되면 data segment, 아니면 bss segment) 라는 곳으로 들어가는데, 일반적으로 최대 크기에 제한이 없습니다. 단 위와 같이 일반적인 배열로 잡는다면 잡고자 하는 크기에 해당하는 연속공간이 있어야 합니다. 하지만 최근의 시스템이라면 400메가바이트 정도의 연속공간은 충분할 듯 싶습니다. 방금 실험해봤는데 랩탑에서 int 로 1.2 기가바이트도 잡히더군요.
dynamic 은 heap을 잡는데... 느립니다. 일반적으로는 성능에 큰 영향이 없지만 다른 분께서 말씀하셨듯 몇백메가를 매우 빈번히 잡는 수준이라면 상당히 성능 저하가 있을 듯 합니다.

그리고 또 하나의 limit 이 있는데, array 의 index 를 표현하는 size_t 의 최대 크기를 넘어가는 배열을 할당할 수 없습니다. 당연히, 그 수를 표현할 수 없으니까요. 아마 이 외에 C/C++ compiler 가 일반적으로 강제하는 다른 limit 은 없을 겁니다.

만약 해당 array 가 사용하게 될 메모리 크기를 확실하게 인지하고 있고, 관리하는 데 큰 어려움이 들지 않는 단순한 용도라면 속도를 위해서 static allocation 하는 것은 매우 당연한 선택입니다. Fortran 이 수치 해석에 탁월해 왔던 가장 큰 이유이기도 하죠.

참고로, 리눅스에서 stack 이나 data segment 의 크기를 확인하거나 크기를 바꾸는 것은 ulimit 명령으로 가능합니다.

oldbell의 이미지

직접 해보지는 않았습니다만은
1차원 배열로 처리하면 속도가 더 빠르다는 이야기를 들었습니다. (요새 컴파일러가 좋아서 상관없으려나요?)

인생의 무게를 느껴라. 아는 만큼 보이는게다.

oldbell의 이미지

직접 해보지는 않았습니다만은
1차원 배열로 처리하면 속도가 더 빠르다는 이야기를 들었습니다. (요새 컴파일러가 좋아서 상관없으려나요?)

인생의 무게를 느껴라. 아는 만큼 보이는게다.

댓글 달기

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