운영 개선

확장 가능한 메모리 할당 자 사용을 고려하십시오

메모리 할당자는 사용자 애플리케이션으로부터 메모리 요청 ( malloc()) 및 응용 프로그램에서 사용할 수있는 메모리 위치의 주소로 응답합니다. 응용 프로그램이 메모리를 다 사용하면이 메모리를 할당 자에게 반환 할 수 있습니다. free()). 대부분의 응용 프로그램에서 메모리가 중심 역할을한다면 메모리 할당 기의 성능이 매우 중요합니다.

운영 체제 및 C 표준 라이브러리 구현과 함께 제공되는 대부분의 범용 할당자는 고도로 다중 스레드 응용 프로그램 내에서 사용될 때 여러 가지 함정을 겪을 수 있습니다.

  • 필요한 것보다 많은 메모리 블록을 운영 체제에 요청합니다. 운영 체제에 대한 각 요청은 시스템 호출을 발생 시키며, 요청 된 CPU는 더 높은 권한 레벨로 전환하고 커널 모드에서 코드를 실행해야합니다. 할당자가 필요한 것보다 많은 양의 메모리를 할당하기 위해 운영 체제에 요청하면 응용 프로그램의 성능이 저하 될 수 있습니다.
  • 상호 배제를위한 동시성 프리미티브 사용. 많은 범용 할당자는 다중 스레드 응용 프로그램에 사용하도록 설계되지 않았으며 중요한 섹션, 뮤텍스 또는 기타 동시성 기본 요소를 보호하기 위해 정확성을 강화하는 데 사용됩니다. 멀티 스레드 응용 프로그램에서 사용될 때 (직접 또는 간접적으로) 뮤텍스를 사용하면 응용 프로그램의 성능에 부정적인 영향을 줄 수 있습니다.

대부분의 GNU / Linux 운영 체제에서 사용되는 범용 할당자는 ptmalloc2 또는 그 변형입니다. ptmalloc2는 메모리 오버 헤드가 적지 만 요청이 여러 스레드에서 만들어 짐에 따라 확장하기가 어렵습니다. 따라서 프로파일 링에서 장면이 malloc()/free() 범용 할당자를 확장 가능한 대안으로 교체하는 것을 고려할 수 있습니다.

내부적으로 Geolib3-MT는 중요한 경로에서 메모리에 대한 일부 요청을 만족시키기 위해 jemalloc을 포함하여 메모리 할당을 처리하기 위해 많은 기술을 사용합니다.

가능한 경우 맞춤형 Ops를 스레드 안전으로 표시

Geolib3-MT는 위치를 병렬로 요리하여 여러 코어로 확장 할 수 있도록 설계되었습니다. Op는 다음을 호출하여 스레드로부터 안전하지 않다고 선언 할 수 있습니다. FnGeolibCookInterface::setThreading()이 경우 Op. 이렇게하면 다른 스레드 안전하지 않은 Ops가 요리하는 장소를 막을 수 있으므로 장면 탐색시 비효율적 인 포켓이 발생할 수 있습니다. 장면을 프로파일 링 할 때 먼저 모든 스레드 안전하지 않은 Op를 식별하고 변환하십시오.

스레드 안전하지 않은 Ops는 Render Log: Op 트리에서 스레드 안전하지 않은 Op가 발견되면 경고가 발행됩니다.

[WARN plugins.Geolib3-MT.OpTree] : Op (<opName> : <opType>)가 ThreadModeGlobalUnsafe로 표시되어 성능이 저하 될 수 있습니다.

가능한 경우 맞춤 운영 체제를 접을 수있는 것으로 표시

실제 장면에는 다음과 같은 Op Chain 구성이 많이 있습니다.

이것은 다목적 성을 고려할 때 여러 가지 이유로 발생할 수 있습니다. AttributeSet 노드, 그들은 자주 사용됩니다 hotfix 렌더 타임에 지정된 활성화 속성이 있는지 확인하는 장면. 또는 Ops 시퀀스는 주어진 노드 그래프를 작성하는 동안 수행 할 일련의 논리적 단계를 나타낼 수 있습니다. 그러나 유사한 Ops 체인은 Geolib3-MT의 잠재적 인 오버 헤드와 최적화 기회를 나타냅니다. 운영 개선.

장면은 Oplib의 토폴로지를 최적화하는 Geolib3-MT 기능을 활용할 수 있습니다. 맞춤 운영팀은 전화를 통해 접을 수 있음을 나타낼 수 있습니다. FnGeolibCookInterface::setOpsCollapsible(). 이 기능은 FnAttribute::StringAttribute 접힌 Ops의 인수가 전달되는 속성의 이름을 나타내는 값을 매개 변수로 사용합니다.

예를 들어, 4의 체인을 고려하십시오 AttributeSet 위의 작전. Geolib3-MT는 각 Op에 대한 Op 인수를 수집하여이 Ops 체인을 축소합니다. GroupAttribute 호출 batch하위에 체인에있는 각 op의 Op 인수가 포함되어 있습니다.

  • 일괄
    • Op1
    • Op2
    • Op3
    • Op4

노트 :  Op 인수는 축소 된 Op로 하향식으로 전달됩니다.

사용자 지정 사용자 Ops는 전화를 걸어 Op Chain 축소 기능에 참여할 수 있습니다. setOpsCollapsible() 위에서 설명한대로. 위의 예에서 AttributeSet 전화 setOpsCollapsible(“batch”) 그런 다음 배치 모드에서 배치 모드로 실행 중인지 테스트합니다. cook() 요구.

Op 체인 붕괴 시스템에 참여하는 경우, Op는 축소 된 Ops 체인 처리 결과가 각 체인을 순차적으로 처리하는 것과 동일해야 함을 보증합니다. 이것의 의미는 주로 붕괴 된 체인에 의해 그 위치 또는 속성이 생성되거나 수정 될 수있는 업스트림 위치 또는 속성의 질의에 관한 것이다. 구체적인 예로, 첫 번째 Op가 속성을 설정하는 2-Op Chain을 고려하십시오. hello=world and the second Op in the chain prints Hi There! if hello is equal to world. If the second Op uses Interface::getAttr() to query the value of hello in the collapsed chain the result is empty, as hello has been set on the location’s output but did not exist on the input. 이를 해결하기 위해 op를 리팩토링하여 호출 할 수 있습니다. getOutputAttr() 대신에.

Cache frequently accessed attributes

While access of an FnAttribute의 데이터는 저렴합니다. FnAttribute 객체는 참조 카운트를 수정해야합니다. 이것은 일반적으로 문제가 아니지만 많은 임시 또는 단명 한 사람을 만드는 Ops에 누적 될 수 있습니다. FnAttribute 특히 많은 스레드가 한 번에 Op를 실행하는 경우경우에 FnAttribute 인스턴스가 자주 사용되는 경우이 오버 헤드를 피하기 위해 캐시되는지 여부를 고려하십시오.

구체적인 예로 다음과 같은 OpScript 스 니펫을 고려하십시오.

로컬 함수 generateChildren (count)

i = 1 인 경우 카운트

로컬 이름 = Interface.GetAttr (“data.name”). getValue () .. tostring (i)

Interface.CreateChild (이름)

종료

종료

이 함수는 입력 속성에서 파생 된 이름으로 개수 하위를 만듭니다. data.name. 카운트가 큰 경우 루프 내에서이 속성에 액세스하면 두 가지 이유로 불필요한 작업이 발생합니다.

  • 루아는 객체를 할당하고 할당 해제해야합니다. data.name 각 반복의 속성을 지정하여 가비지 콜렉터에 더 많은 작업을 발생시킵니다.
  • 이 할당 및 소멸은 속성의 원자 참조 카운트를 증가 및 감소시켜 잠재적으로 스레드간에 스톨을 발생시킵니다.

두 번째 병목 현상은 동일한 속성 세트에 액세스하는 OpScript가 많은 스레드에서 실행될 때 적용됩니다. 참조 횟수에 너무 자주 액세스하지 않도록하기 위해이 스 니펫은 다음과 같이 다시 작성할 수 있습니다.

로컬 함수 generateChildren (count)

로컬 스템 = Interface.GetAttr (“data.name”). getValue ()

i = 1 인 경우 카운트

현지 이름 = stem .. tostring (i)

Interface.CreateChild (이름)

종료

종료

지금 data.name 루프 외부에서 한 번만 액세스되므로 루프가 실행되는 동안 참조 카운트는 건드리지 않습니다.