2010-01-08 7 views
7

공유 라이브러리와 정적 라이브러리 로딩 시간에 대한 질문이 있습니다.공유 라이브러리 대 정적 라이브러리 로딩 시간

liba, libb, libc를 사용하는 실행 가능한 foo.exe가 있다고 가정합니다. 또한 주어진 시간에 컴퓨터에서 실행되는 실행 파일 인스턴스가 10 개 이상 있습니다.

위의 3 개의 라이브러리가 공유 라이브러리 인 경우 : 첫 번째 Insance가 RAM에로드되었습니다. foo.exe의 main()이 메모리를로드하는 데 걸리는 시간 (무시할 수 있음) +로드 시간 liba + libb를로드 할 시간 + libc로드 시간 두 번째 인스턴스가 시작되었습니다. 이제이 실행 파일의 두 번째 인스턴스가 실행된다고 가정합니다. 모든 라이브러리 이 주 메모리에 이미로드되었으므로 무시할 수있는 메모리에 main()을로드하는 데 걸린 시간이 소요됩니다.

이제 상기 3 라이브러리 정적 라이브러리 인 경우 : 1 Insance이 RAM에로드된다에서 foo.exe로 main()에 의해 촬영 시간이 될 것이다 걸리는 시간을 메모리 (ITS 무시할 가정)로드 될 + 시간이 load liba + libb를로드 할 시간 + libc를로드하는 시간 (Offcourse : 전체 실행 파일의 모든 부분) 두 번째 인스턴스가 시작되었습니다. 이제이 실행 파일의 두 번째 인스턴스가 실행된다고 가정합니다. 소요 된 시간은 foo.exe의 main()이 메모리를로드하는 데 걸리는 시간 (무시할 만하다) + liba를로드 할 시간 + libb를로드하는 시간 + libc를로드하는 시간. (각 실행 파일은 정적 라이브러리이므로 librareies를 공유하지 않기 때문에)

결론적으로 정적 라이브러리에서는로드 시간이 더 길어집니다. 하지만 공유 라이브러리는 정적 라이브러리보다로드하는 데 시간이 더 오래 걸리므로 지연이 있으므로 공유 라이브러리가 좋은 옵션이 아닙니다. 이것이 어떻게 가능한지 ?

답변

9

연결 (참조 해결)은 무료가 아닙니다. 정적 링크를 사용하면 바이너리가 생성 될 때 단번에 해상도가 완료됩니다. 동적 연결을 사용하면 바이너리가로드 될 때마다이를 수행해야합니다. 공유 라이브러리에서 실행되도록 컴파일 된 코드는 정적으로 링크되도록 컴파일 된 코드보다 효율적이지 않을 수 있습니다. 정확한 비용은 아키텍처와 시스템의 동적 연결 구현에 따라 다릅니다.

라이브러리를 동적으로 만드는 비용은 32 비트 x86 명령어 세트의 경우 상대적으로 높을 수 있습니다. ELF binary format에서 이미 부족한 레지스터 중 하나를 희생시켜 동적으로 링크 된 코드를 재배치 할 수 있습니다. 이전 a.out 형식은 각 공유 라이브러리를 고정 된 위치에 배치했지만 확장되지 않았습니다. Mac OS X에는 동적 라이브러리가 주소 공간의 미리 결정된 위치에 배치되지만 개별 컴퓨터의 규모에서 충돌이 해결되었을 때 중간 시스템이 있다고 믿습니다 (새로운 "긴급"시스템 성능 최적화 "단계 소프트웨어). 어떤면에서이 시스템 (pre-binding)을 사용하면 케이크를 먹을 수도 있습니다. Apple이 amd64 아키텍처로 거의 전환 했으므로 미리 바인딩이 필요한지 나는 알지 못합니다.

또한 현대의 OS에서 정적 및 동적 링크 코드는 사용되는 경우에만 디스크에서로드 (페이징 됨)되지만 사용자의 질문과 직각입니다.

+0

이 믿을 수 없을 정도로 빠른 응답을 많이 주셔서 감사합니다, 우리는 2 architecural scenarious 나는 내 질문 pls에 대한 답변으로 내 질문을 준있다. – sud

2

정적 라이브러리는 컴파일 된 시간에 링크되고 공유 라이브러리는 런타임에 링크됩니다. 따라서 정적 라이브러리를 사용하는 실행 파일은 디스크에 쓰여지 기 전에 모든 링크 시간을 상각합니다.

+0

는 3 라이브러리 LIBA, libb가있는 경우. 현재 3 개의 lib를 모두 사용하는 foo1.exe와 foo2.exe의 두 가지 실행 파일이 있습니다. 1. foo1.exe의 인스턴스가 여러 개 실행되면 텍스트 페이지를 공유합니다. 이게 옳은 거니 ? 2. foo1.exe와 foo2.exe를 동시에 실행하면 텍스트 페이지를 공유하지 않습니다. 이게 옳은 거니 ? Pls 알려주세요 – sud

+0

정적 링크 후에 라이브러리가 더 이상 존재하지 않기 때문에 첫 번째 경우 공유되는 텍스트 페이지는 실제 라이브러리가 아닌 foo1의 텍스트 페이지가됩니다. 그렇지 않으면 둘 다 올바르다. –

0

믿을 수 없을 정도로 빠른 응답에 대해 감사드립니다. 우리는 2 architecural scenarious 있습니다 :

Q1.Architecure-1 : exe 크기가 3GB라고 가정합니다 (정적 라이브러리). 이러한 큰 크기의 exe는 로딩 할 때 더 많은 시간이 걸릴 것입니다 (정적 라이브러리라고 가정). 또는이 exe를 연결하는 데 더 많은 시간이 걸릴 것입니다 (공유 라이브러리를 사용한다고 가정하고 모든 라이브러리가 이미있는 경우). 메모리에만 연결해야합니다.)

Architecure-2 : exe 크기가 1.5GB (95 % lib + 5 % main())이고 동시에 6 개의 인스턴스가 동시에 실행되고 있다고 가정합니다. 이 6 개의 인스턴스가 올라 오면,이 6 개의 인스턴스의 초기로드 및 링크 중에 추가 지연을 취할 준비가되어 있다고 가정하고 며칠 동안 실행합니다.

2. 이제는 정적 객체가 아닌 공유 객체를 사용하고 있다면 6 개의 인스턴스간에 모든 라이브러리가 공유되므로 RAM에 많은 여유 공간이 생깁니 까? RAM에서 페이지 스와핑을 줄이는 더 많은 공간 때문에 실시간 실행 속도가 향상되지 않습니까?

3. '맵'파일을 사용하여 내 보낸 심볼 수를 줄이면 (공유 라이브러리를 통해서만 가능함) 심볼 테이블 크기가 줄어들지 않고 런타임 성능이 향상되지 않습니까? 모든 정적 lib에있는 libc의

감사 수드

+0

동일한 프로그램 (원래 질문에서 "foo.exe")의 인스턴스를 실행하는 것을 의미하는 경우 코드는 정적 링크 된 버전과 동적으로 링크 된 버전과 동일한 메모리 (모든 이점 포함)로 공유됩니다. –

+0

약간 다른 프로그램 foo1.exe, foo2.exe를 사용하는 경우에만 각각 동일한 liba, libb, lic을 사용하므로 동적 연결에 이점이 있습니다. 이 경우에만 정적 링크와 공유 할 수없는 것을 공유 할 수 있습니다. –

+0

실제로 나는 동일한 실행 파일 foo.exe (정적 라이브러리 사용)가 foo1, foo2 대신에 6 개의 인스턴스를 가지고 있다고 말하고자합니다. 그러나이 경우 코드가 메모리에서 어떻게 공유 될 것입니까? 각각의 인스턴스는 RAM에 자체 복사본이 있습니까? 나는 정적 라이브러리가 아닌 공유 라이브러리 만 생각했다. 나를 계몽 할 수있는 URL을 제공 할 수 있습니까? – sud

관련 문제