2011-01-20 2 views
7

"삭제"기능의 실행 속도가 느린 C++ 응용 프로그램이 있습니다. 이 문제의 원인은 무엇이며 어디에서 솔루션을 찾기 시작해야합니까?C++ "delete"가 느립니다. 먼저 어디를 봐야합니까?

배경 :

이 C++ 코드는 기본적으로 단지 DLL이다의 AutoCAD의 내부 실행하는 ARX 파일에 있습니다.

삭제가 느린 특정 컴퓨터는 AutoCAD 2011, Windows 7, 64 비트를 실행 중입니다. AutoCAD 2011 용 ARX는 Visual Studio 2008 서비스 팩 1을 사용하여 컴파일해야합니다.

문제가 발생한 컴퓨터는 고객의 컴퓨터입니다. 여기에는 Visual Studio의 모든 버전이 설치되어 있지 않습니다. 내 개발 컴퓨터에서

는, 코드가 테스트하려면 AutoCAD를 2011 년

에 문제가없는, 내가 링크 된 목록을 삭제합니다 일부 코드가 있습니다. 문제가있는 컴퓨터에서는 목록을 삭제하는 데 0.7 초가 걸립니다. 문제가없는 컴퓨터 및 구성에서는 동일한 코드에 0.02 초가 소요됩니다. 특정 시간은 중요하지 않습니다 - 두 숫자 사이에 큰 차이가 있습니다.

두 컴퓨터에서 동일한 버전의 코드를 실행해야하므로 릴리스 대 디버그 빌드 문제가 아닙니다.

+1

목록에있는 항목의 수와 크기는 얼마입니까? –

+2

벤치 마크에 사용하고있는 테스트 코드를 공유하십시오. – karlphillip

+0

그리고 두 시스템에서 정적/동적으로 링크하고 있습니까? 디버그/릴리스 빌드를 비교하고 있지 않은지 확인하십시오. –

답변

5

대략 순서대로 내가 그들을 확인할 것 :

  • 다른 플러그인 : 그 행동이 다른 ARX 파일에 의한 수 있을까? 그들이 나쁜 시스템에서 사용할 수 없습니까?
  • PerfMon : 삭제하는 동안 소프트/하드 페이지 오류 또는 캐시 누락이 최대치인지 확인하십시오. 고객 컴퓨터에서 소프트/하드 페이지 오류 또는 캐시 누락이 피크인지 확인하십시오.
  • HeapQueryInformation : 좋은/나쁜 환경에서 동일한 값이 있습니까?
  • 힙 잠금 : 다른 스레드가 힙의 잠금 장치를 꽉 잡고 배경에서 매우 활성 상태 일 수 있습니까? HeapLock/HeapUnlock (물론 잠금 시간 안에 루프)을 감싸서 테스트 할 수 있습니다.
  • 후크 : 각 코드를 걸 수 있습니까? (예 : C++/Win32 힙 기능에 연결하여 원하는 기능을 수행하는 타사 앱)
  • 빨대 쥐기 : 각각 new의 처리 시간이 현저히 오래 걸리나요? 개별 delete 시간은 어떻게 분배됩니까?
1

작동/실패 시스템 간의 캐시 효율이 다르기 때문일 수 있습니다. 실패한 시스템에서 더 많은 메모리 조각화가 발생하여 큰 삭제로 인해 캐시가 스 래시됩니다. 대기중인 시스템에서는 데이터가 더 순차적으로 끝나고 큰 삭제 중에 더 많은 캐시 히트를 얻을 수 있습니다.

인텔 성능 카운터 모니터를 사용해보십시오.

1

허용 가능하고 가능한 경우 고객의 컴퓨터에서 프로파일 러를 사용해보십시오.

AMD CodeAnalyst 또는 인텔 프로파일 러를 사용해 볼 수 있습니다 (단 하나는 무료가 아님).

그럴 수 없다면 릴리스 빌드에 프로파일 링 코드를 추가하고 고객으로부터 결과를 수집하십시오. 간단한 프로파일 링 코드조차도 실제 병목 현상을 찾는 데 도움이 될 수 있습니다.

삭제 자체가 문제는 아니지만 문제는 코드의 다른 부분 일 수 있습니다.

예. - head->resval.rstring 유형은 무엇입니까?

0

우리는 항상이 문제에 부딪 힙니다. 코드에 아무런 문제가 없으므로 수천 개의 항목을 삭제하면 릴리스 모드에서도 몇 분이 걸릴 수 있습니다.

대답은 삭제하지 않는 것입니다. 실제 메모리 할당자를 얻고 각 객체를 개별적으로 할당하는 대신 메모리 풀 (또는 사용자 정의 힙 또는 원하는 모든 호출)을 만듭니다. Nedmalloc이 우리가 사용하고 권장하는 것이며 "nedpool"을 만들 수 있습니다. 기본적으로 풀은 객체가 할당되는 메모리 블록입니다. 각 객체에 대해 여전히 메모리를 할당하지만 OS에서 직접 가져 오는 것이 아니라 풀에서 가져옵니다.

삭제할 시간이되면 개체를 하나씩 삭제하지 않고 전체 풀만 삭제하면됩니다. 동시에 만료 될 객체 배치마다 다른 풀을 사용하십시오. 전체 풀에 대해 메모리를 할당 할 필요는 없지만 모든 것을 한 번에 삭제할 수 있습니다.

+0

이렇게하면 대부분의 C++ 객체에 정의되지 않은 동작이 발생합니다. 적어도 호출 할 수있는 포함 된 객체의 소멸자를 준비해야합니다. –

+0

물론. 새 위치에서 직접 소멸자를 직접 호출해야하지만 메모리를 할당 해제하지 않아야합니다. –

0

리 트리스트는 어떻게 생성됩니까? 또한 acutNewRb 및 acutRelRb를 사용하는 대신 수동으로 resbufs를 할당하고 삭제하는 이유가 있습니까?

사용자가 아마 이것을 선택했을 것입니다 만, AutoCAD 2009와 2011 모두에 기본 도면이로드되어 있습니까? 그렇지 않은 경우 도면은 동일하며 (ACAD 버전 제외) 로컬 또는 네트워크 드라이브에 있습니까? 사용자가 두 인스턴스에서 실행중인 동일한 lisp/.Net/objectARX 응용 프로그램을 가지고 있는지 여부를 확인할 수도 있습니다. 또한 AutoCAD 2011은 네트워크 또는 로컬 설치입니까?

마지막으로 질문에 autocad 및 objectarx 태그를 추가 할 수 있습니다.

+0

acutBuildList를 사용하여 retList가 생성 중입니다. acutRelRb를 사용하여 메모리를 릴리스했지만 코드를 프로파일 링하는 동안 해당 함수가 문제가되는 것으로 나타났습니다. 필자는 수동으로 다시 작성하여 문제를 해결할 수 있는지 (문제가 아닌지) 확인하고 문제의 원인을 파악할 수있게했습니다. 모든 경우에 동일한 도면에서 코드를 실행하고 있습니다. –

관련 문제