문제

MSXML6과 XML 메시지를 지속적으로 구문 분석하는 다중 스레드 서버 C ++ 프로그램이있는 다음 준비된 XSLT 변환을 적용하여 텍스트를 생성합니다. 4 CPU가있는 서버에서 이것을 실행하고 있습니다. 각 스레드는 완전히 독립적이며 자체 변환 객체를 사용합니다. 스레드간에 COM 객체를 공유하지 않습니다.

이것은 잘 작동하지만 문제는 확장 성입니다. 실행할 때 :

  1. 하나의 스레드를 사용하면 스레드 당 약 26 개의 구문 분석+변환이 발생합니다.
  2. 2 개의 스레드가 있으면 약 20/s/스레드가 발생합니다.
  3. 3 개의 스레드, 18/s/스레드.
  4. 4 개의 스레드, 15/s/스레드.

스레드 사이에 공유되지 않은 것이 없기 때문에 근처에 근거리 확장 성이 예상되었으므로 1보다 4 개의 스레드로 4 배 빠를 수 있어야합니다. 대신 2.3 배 더 빠릅니다.

고전적인 경합 문제처럼 보입니다. 내 코드에 경합이있을 가능성을 제거하기 위해 시험 프로그램을 작성했습니다. 문서가 스레드간에 공유되지 않기 때문에 불필요한 잠금을 피하기 위해 FreethreadeddomDocument One 대신 DomDocument60 클래스를 사용하고 있습니다. 나는 캐시 라인 허위 공유의 증거를 열심히 보았고 적어도 내 코드에는 아무것도 없습니다.

또 다른 단서, 컨텍스트 스위치 속도는 각 스레드에 대해> 15k/s입니다. 범인이 MSXML 내의 COM 메모리 관리자 또는 메모리 관리자라고 생각합니다. 어쩌면 모든 메모리 할당/거래에 대해 획득 및 릴리스 해야하는 글로벌 잠금 장치가있을 수 있습니다. 나는이 시대에 메모리 매니저가 멀티 스레드 멀티 CPU 시나리오에서 잘 조정되는 방식으로 작성되지 않았다는 것을 믿을 수 없습니다.

누구 든지이 논쟁의 원인이나 그것을 제거하는 방법을 알고 있습니까?

도움이 되었습니까?

해결책 3

답변 주셔서 감사합니다. 나는 두 가지 제안의 혼합을 구현하게되었습니다.

C#에서 COM+ ServicedComponent를 만들고 COM+에서 별도의 서버 프로세스로 호스팅했으며 XSLCompileDtransform을 사용하여 변환을 실행했습니다. C ++ 서버는 COM을 사용 하여이 외부 프로세스에 연결하여 XML을 보내고 변환 된 문자열을 다시 얻습니다. 이것은 성능을 두 배로 늘 렸습니다.

다른 팁

힙 기반 메모리 관리자 (기본 malloc/free)가 단일 뮤트를 사용하는 것이 일반적입니다. 힙 메모리 영역은 단일 일관된 데이터 구조입니다.

이 제한이없는 대체 메모리 관리 전략 (예 : 계층 적 할당 자)이 있습니다. MSXML에서 사용하는 할당자를 사용자 정의해야합니다.

또는 각 MSXML 작업자마다 별도의 프로세스를 사용하여 멀티 스레드 아키텍처에서 멀티 프로세스 아키텍처로 이동하는 것을 조사해야합니다. MSXML 작업자는 문자열 데이터를 입력 및 출력으로 사용하므로 직렬화 문제가 없습니다.

요약 : 멀티 프로세스 아키텍처를 사용하면 문제에 더 잘 맞고 확장이 더 좋을 것입니다.

MSXML은 BSTRS를 사용하여 힙 관리의 글로벌 잠금 장치를 사용합니다. 그것은 몇 년 전에 대규모 다중 앱에 많은 어려움을 겪었습니다.

앱에서 XML 사용을 제거했습니다.이 작업을 수행하지 못할 수도 있으므로 대체 XML 파서를 사용하는 것이 좋습니다.

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