2013-07-04 2 views
2

이 주제에 비슷한 게시물을 찾았지만 성능보다는 디자인 측면을 다루었 기 때문에 커다란 C 파일의 파괴가 컴파일 및 실행 시간에 미치는 영향을 이해하기 위해 게시하고 있습니다. .하나의 파일을 여러 파일로 분할하는 C - 성능 aspect

큰 utils 파일이 있습니다. (우리 모두는 빠르게 성장한다는 것을 알고 있습니다.) 모듈 기반 함수 파일 (cookies.c, memcacheutils.c, stringutils.c, search.c, sort.c, arrayutils.c 등)로 파일을 분할하는 경우 컴파일 및 실행 시간에 페널티가 추가되는지 이해하려고합니다. .

내 상식은 코드가 이제 동일한 파일이 아니라 멀리 가져 오기 장소에서 포인터를 찾아야하므로 약간의 불이익을 추가한다고합니다.

나는 잘못되었거나 부분적으로 정확할 수 있습니다. 모든 전문가의지도를 구하십시오. 나의 현재 utils 파일은 약 150k이고 80+ 함수이다.

게시물을 읽어 주셔서 감사합니다.

+0

프로젝트의 성과 시간 패널티 대 개발 시간 패널티를 예측해야합니다. 큰 파일을 작은 파일로 나누는 것은 일반적으로 하나 또는 여러 레벨의 포인터 간접 지정을 추가하지만 개발자 또는 유지 보수 작업을 쉽게 수행 할 수 있습니다. – lucasg

+0

유지 관리를 위해이 괴물을 조각으로 잘라냅니다! – alk

+0

Microsoft Windows 프로젝트는 모든 파일에 대해'windows.h'를 가져 오려면 헤더 캐싱없이 * 영원히 * 사용할 수있는 영역입니다. 코드를 여러 파일로 분할하여 컴파일 성능이 손상 될 수 있는지 여부를 묻는 것은 합당한 질문입니다. –

답변

2

다른 세그먼트가있는 16 비트 PC를 사용할 때 사용됩니다. 멀리 (그리고 더 나쁜 것은 "huge") 포인터는 세그먼트 레지스터를 속여서 시작해야하기 때문에 성능 비용이 들게되었습니다.

요즘 32 비트 주소 지정을 사용하면 비용이 들지 않습니다.궁극적으로 성능에 대해 걱정한다면 어셈블리에서 "jump tables"을 고려하기 시작합니다. 대상 주소가 현재 명령어에 비해 짧은 거리에 있어야합니다.

C에서는 코드를 다른 모듈에 넣으려고합니다 (소프트웨어 "응집력"및 "결합"이론적 문제). 실행 시간에는 차이가 없어야합니다. 컴파일 시간까지는 "의존"합니다 - 특히 파일을 반복해서 포함하는 경우. 변경된 코드 단위 만 다시 컴파일 할 수 있으므로 여러 파일을 가지고있는 큰 프로젝트에서 막대한 시간을 절약 할 수 있습니다. 작은 프로젝트 컴파일 시간은 효율성면에서 상대적으로 중요하지 않을 정도로 작습니다.

+0

16 비트 컴파일러와 함께 항상 작은 메모리 모델을 사용할 수 있으며 아무런 차이가 없습니다. – Hogan

+0

@Hogan이 동의했습니다. 그러나 대용량 메모리 모델의 성능에 미치는 영향은 당시로서는 현실이었습니다. –

+1

분리 된 편집 단위와 메모리 모델은 완전히 직각이됩니다. –

1

컴파일 시간이 변경됩니다.

(주 -. 빨리 얻을 것 증분 빌드를 할 수있는 시스템 및 프로젝트)

파일로 침 한 후 최종 결과는 변하지 않을 것 외에 코드에 대한 변경이없는 경우.

코드에 디버그 정보를 포함하면 최종 코드 결과가 더 많은 파일로 변경되지만 성능 차이는 기대하지 않을 것입니다.


사이드 노트는 파일을 분할하지 말라고 알려주는 대형 시스템으로 작업 한 단일 프로그래머가 있다고 생각하지 않습니다. 대형 시스템을 유지 보수 할 수 있도록하기 만하면됩니다. 귀하의 시스템이 아직 그 시점에 있다고 말할 수는 없지만 조기에 해를 입힐 수는 없습니다. 파일을 분할합니다.

+0

"컴파일 시간이 변경 될 것입니다". 더 빠르거나 느릴 것입니까? 많은 오브젝트 파일이 .cpp 파일 내에서 아무 것도 바뀌지 않을 때 다시 컴파일 할 필요가 없기 때문에 더 빠른 것으로 가정합니다. – hetepeperfan

+0

@hetepeperfan - 컴파일러와 링커 및 make 프로세스에 따라 다릅니다. 나는 시스템이 더 빨라지고 시스템이 더 느려지는 시스템을 사용했습니다. – Hogan

3

항상 원본을 논리 단위로 구분해야합니다.

이렇게하면 모든 단일 변경에 대해 모든 것을 다시 컴파일 할 필요가 없으므로 빠른 컴파일 작업에 유리합니다. 또한 그러한 원천을 유지하는 것은 기껏해야 끔찍하며 생산 관련 변화를 추적하는 것도 문제가됩니다.

함수가 다른 모듈에 상주하는 경우에는 성능 이득/페널티가없고, 최악의 경우 하나의 추가 jmp 명령이됩니다. 코드가 실제로 기계주기에 의존하는 경우 먼저 알고리즘 설계를 고려해야합니다.

+0

더 빠른 컴파일은 빌드 시스템과 컴파일러에 달려 있습니다. 이 속도 범프를 제공 할 수없는 많은 컴파일러가 있습니다. – Hogan

4

일반적으로 프로젝트를 여러 컴파일 단위로 분할하면 더 나은 프로젝트 관리와 신속한 부분 편집이 가능합니다. 한 파일을 편집 할 때 컴파일 단위를 다시 컴파일하고 다시 연결하여 & 디버그를 테스트하면됩니다.

컴파일러에 따라 하나의 파일에 모두 추가 인라인 및 기능 최적화가 가능할 수도 있지만 컴파일러에 따라 다릅니다. 모두 컴파일 시간을 요합니다.

+0

여러 파일에 침을 뱉을 때 속도가 느려지는 프로젝트를 보았습니다 ... 컴파일이 더 빠르다고 말하는 것은 광범위하지 않습니다. – Hogan

+1

그래서 내가 더 빨리 ** 부분적으로 ** 컴파일을했다. –

+0

아, 기술적으로 나를 잡았어. 공정한. 나는 당신의 대답을 오해 할 수 있다고 생각합니다. – Hogan

1

이렇게해도 성능이 저하되지는 않습니다. 그리고 그렇게하더라도 조기에 최적화됩니다. 중요한 것은 개발 시간뿐입니다.

당신은 이미 모든 알고리즘이 최적의 복잡성을 가지며 최대한의 성능을 위해 모든 내부 루프를 조정했음을 알게되고 런타임에서 몇 피코 초를 줄여야 할 필요가있는 경우 항상 소스 파일은 단순히 #include 모든 분할 소스를 하나의 큰 덩어리로 컴파일러에 공급합니다.

0

런타임 성능에 관해서는 성능 손실 측면에서 얼마나 민감해야하는지에 따라 일부 성능 측정을 실행하는 것이 좋습니다. 지금까지의 답변에 대한 합의는 파일을 작은 단위로 나눔으로써 런타임 성능이 저하되지는 않지만 성능에 대한 정의에 달려 있다는 것입니다. 당신은 당신이 whole program optimization가 활성화되어, 그것이 효과적인 경우를 제외하고, 파일이 분할되는 경우 컴파일러가 최적화를위한 몇 가지 기회를 놓칠 것이라는 약간의 가능성이, 조금이라도 성능 손실에 대해 정말 우려되는 경우

(따라 물론 코드 스타일, 전역 변수 사용, 인라인 사용 (경우에 따라 인라인하지 않으면 더 나은 결과를 얻을 수 있음), C++을 사용하는 경우 정적 클래스/메서드 등).

일부 경우에는 단일 소스 파일을 사용하면 성능이 크게 향상 될 수 있으며 다른 경우에는 성능이 저하 될 수 있습니다. 컴파일러의 최적화 수준을 변경하는 것을 포함하여 몇 가지 간단한 시나리오를 전후로 테스트하는 것은 상당히 흥미로운 실험이 될 것입니다.

"관련 함수를 많은 양의 소스 파일로 나눠도 괜찮습니다."와 같은 어려운 규칙을 찾을 수는 없을 것이라고 생각하지만 특정 컴파일러 설정과 소스 파일을 사용하여 파일을 분할하면 성능 테스트의 미세성 정도에 따라 명령어 캐시의 성능에 영향을 미치는 미묘한 차이가 발생할 수도 있습니다.

관련 문제