공유 LIB를 사용할 때 Linux에서 앱의 시작이 느려지는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1410691

  •  05-07-2019
  •  | 
  •  

문제

내가 작업중인 내장 장치에서 시작 시간은 중요한 문제입니다. 전체 응용 프로그램은 라이브러리 세트를 사용하는 여러 실행 파이브로 구성됩니다. 플래시 메모리의 공간이 제한되어 있기 때문에 공유 라이브러리를 사용하고 싶습니다.

애플리케이션은 공유 라이브러리와 컴파일되고 연결될 때 평소와 같이 작동하며 플래시 메모리의 양이 예상대로 감소됩니다. 정적 LIBS에 연결된 버전의 차이점은 응용 프로그램의 시작 시간이 약 20 초 더 길며 그 이유를 모릅니다.

응용 프로그램은 Linux 2.6.17 OS, 16MB 플래시 (JFFS 파일 시스템) 및 32MB RAM을 사용하여 180 MHz에서 ARM9 CPU에서 실행됩니다.

도움이 되었습니까?

해결책

Bacause 공유 라이브러리는 일반적으로 dlopen () 또는 유사한 것들에 의해 런타임에 링크되어야합니다. 정적 라이브러리에는 그러한 단계가 없습니다.

편집 : 좀 더 세부 사항. Dlopen은 다음 작업을 수행해야합니다.

  • 공유 라이브러리를 찾으십시오
  • 메모리에로드하십시오
  • 모든 종속성을 재귀 적으로로드하십시오 (및 그 종속성 ....)
  • 모든 기호를 해결하십시오

이를 위해서는 많은 IO 작업이 필요합니다.

정적으로 연결된 프로그램에서 위의 모든 것은 런타임이 아닌 컴파일 시간에 수행됩니다. 따라서 정적으로 연결된 프로그램을로드하는 것이 훨씬 빠릅니다.

귀하의 경우, 차이는 코드가 실행 해야하는 비교적 느린 하드웨어에 의해 과장됩니다.

다른 팁

이것은 속도와 공간의 고전적인 트레이드 오프의 훌륭한 예입니다.

모든 실행 파일이 더 빠르도록 모든 실행 파일을 정적으로 연결할 수 있지만 더 많은 공간을 차지할 수 있습니다.

또는

공간이 적고로드하는 데 더 많은 시간을 할애하는 라이브러리를 공유 할 수 있습니다.

그러니 희생하고 싶은 것을 결정하십시오.

이 차이 (OS, 컴파일러 등)에 대한 많은 요소가 있지만 좋은 이유를 찾을 수 있습니다. 여기. 기본적으로 공유 된 라이브러리는 우주 이유로 만들어졌으며 작업을 수행하기 위해 관련된 "마법"의 대부분은 성능을 얻습니다.

(역사적으로, Linux/Unix의 Original Netscape Navigator는 정적으로 연결된 큰 지방 실행 파일이었습니다).

이것은 비슷한 문제가있는 다른 사람들을 도울 수 있습니다.

내 경우 스타트 업이 오래 걸리는 이유는 GCC의 기본 설정이 라이브러리 내부의 모든 기호를 내보내는 것입니다. 큰 개선은 컴파일러 설정 "-fvisibility = hidden"을 설정하는 것입니다.

LIB가 수출 해야하는 모든 기호는 성명서와 함께 보강되어야합니다.

__attribute__ ((visibility("default")))

보다 GCC 위키
그리고 아주 좋은 기사 공유 라이브러리를 작성하는 방법

좋아, 나는 공유 라이브러리의 사용에 속도에 관한 단점이 있다는 것을 배웠다. 이 기사를 찾았습니다 동적 링크 및 로딩 깨달음. 로딩 프로세스는 내가 예상했던 것보다 훨씬 길게 보입니다.

흥미로운 .. 일반적으로 공유 라이브러리의 시간을로드하는 것은 정적으로 연결된 뚱뚱한 앱에서 눈에 띄지 않습니다. 따라서 시스템이 플래시 메모리에서 라이브러리를로드하는 데 매우 느리거나로드 된 라이브러리가 어떤 식 으로든 확인되고 있다고 추측 할 수 있습니다 (예 : .NET 앱은 모든로드 된 DLL에 대한 체크섬을 실행하여 시작 시간을 상당히 줄입니다. 어떤 경우). 공유 라이브러리가 필요에 따라로드되고 나중에 언로드되어 구성 문제를 나타낼 수 있습니다.

그러니 죄송합니다. 왜 그런지 말할 수는 없지만 ARM 장치/OS에 문제가 있다고 생각합니다. 시작 코드를 계측하거나 가장 일반적으로 사용되는 라이브러리 중 하나와 정적으로 연결하여 큰 차이가 있는지 확인해 보셨습니까? 또한 공유 리브를 LIB의 FS를 검색하는 데 걸리는 시간을 줄이기 위해 앱과 동일한 디렉토리에 넣습니다.

나에게 분명해 보이는 한 가지 옵션은 여러 프로그램을 단일 바이너리에 정적으로 연결하는 것입니다. 이렇게하면 가능한 한 많은 코드를 계속 공유하지만 (아마도 이전보다 더 많은) 동적 링커의 오버 헤드를 피하고 시스템에 동적 링커를 사용하는 공간을 절약 할 수 있습니다.

여러 실행 파이브를 동일한 실행 파일로 결합하는 것은 매우 쉽습니다. 일반적으로 ArgV를 검사하고 그에 따라 호출 할 루틴을 결정합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top