2008-11-05 3 views
1

렌더링 파이프 라인에서 성능을 좀 더 높일 수 있습니다. (가장 먼 곳에서) 가장 느린 부분은 큰 이미지에서 java.awt.imaging.LookupOp를 수행하는 것입니다.조회 연산 성능

이미지 크기는 약 2048x2048입니다.

필자는 드로잉 작업과 함께 필터를 수행하는 것이 필터 메서드를 호출하는 것보다 훨씬 빠르다는 것을 알아 냈습니다. 그러나 이것으로 약 250ms (또는 4fps)의 검색 작업을 수행 할 수 있습니다. 누구든지 렌더링 팁이 있습니까?

Heres는 본질적으로 무엇을 우리가하고있는 :

public void paint(Graphics g) 
{ 
    if(recalcLUT) 
    { 
     Graphics2D g2d = (Graphics2D) displayImage.getGraphics(); 
     g2d.drawImage(srcImage, lut, 0, 0); 
    } 

    Graphics2D g2d = (Graphics2D) g; 
    g2d.clearRect(0, 0, this.getWidth(), this.getHeight()); 
    AffineTransform at = new AffineTransform(); 
    at.setToIdentity(); 
    at.scale(scale, scale); 
    g2d.drawImage(displayImage, at, null); 
} 

LUT 변수는 일반적으로 LookupOp가 ShortLookupOp, 이미지 16 비트 그레이 스케일 이미지

덕분에 내가 아는

Ryan Bucher:

입니다 여기에서 수행 할 수있는 몇 가지 명백한 성능 최적화가 있습니다. 그러나 중요한 문제는 LookupOp 작업을 수행하는 것입니다. 그래서 그것에 관한 조언을 찾고 있습니다.

조회 작업은 본질적으로 배열을 만들고 이미지의 각 픽셀을 색상으로 렌더링하는 대신 색상을 배열의 인덱스로 사용하고 색인의 값으로 색상을 렌더링합니다. 이 특정 예제에서는 Im을 사용하여 간단한 밝기/대비 작업을 수행합니다. rescaleOp를 사용하여 구현할 수도 있습니다. rescaleOp는 기본적으로 모든 픽셀의 값에 선형 함수를 적용하는 방법입니다. 그러나 이것은 느린 것으로 판명됩니다.

답변

1

저는 8 년 가까이 자바를 사용하지 않았으므로 일부 구문은 부적절 할 수 있습니다.

루프와 관련된 모든 종류의 성능의 핵심은 가능한 루프 밖에서 가능한 많은 것들을 밀어 넣는 것입니다. 그런 다음 변경할 수없는 경우 계산을 수행하십시오. 여러 번 변경 사항을 캐시 할 수 있도록 마지막 순간까지 다시 계산할 때까지 기다리는 것이 더 나을 때가 많습니다.

  1. 모든 개체 구성을 렌더 루프 외부로 옮깁니다. 미리 필요한 물체의 수를 알고 있다면 그들을 전달하십시오. 그렇지 않으면 객체 풀을 사용하고 팩토리가 렌더 루프 외부의 객체를 생성하게합니다. 이렇게하면 건설/파괴 시간을 절약 할 수 있습니다.

  2. 눈금이 변경된 경우에만 AffineTransform을 계산하십시오. 이 코드를 페인트 루프 외부로 밀어 넣어 (const 참조로 ... 심지어 Java에 존재합니까?) C++에서 너무 오랫동안 사용했습니다.

  3. at.setToIdentity를 호출 할 필요가 없습니다.) 당신의 AffineTransform은 기본적으로 Identity 행렬이어야합니다 (이것을 체크하십시오)

  4. 모든 프레임을 호출해야합니까? if 문을 실행 한 후 recalcLUT를 false로 설정하는 것이 합리적입니까?

LookupOp의 목표가 무엇인지 확실하지 않습니다. 내가하는 일에 대해 좀 더 많은 정보를 주시면 더 제안 할 수 있습니다.

이 정보가 도움이되기를 바랍니다.

0

이 처리를 GPU로 푸시 할 수 있습니까? 여러 하드웨어 파이프 라인을 사용하면 처리 속도가 크게 향상됩니다.

그렇지 않으면 CPU에서 LookupOp를 병렬 처리해야합니다. 내가 이해하고있는 바에 따르면, 각 조회는 개별적으로 수행 될 수 있습니다. 따라서 여러 개의 스레드 (CPU 아치와 그 밖의 모든 작업이 동시에 얼마나 많은지)에 따라 스레드 수를 늘리고 각 스레드가 이미지의 일부를 조회하도록 할 수 있습니다. 모든 스레드가 완료 될 때까지 기다리려면 각 업데이트 실행시 세마포가 필요합니다.

어떤 경우에도 변경 사항이없는 모든 프레임에 대해 일부 메모리 소비를 절충해야합니다. 프레임 속도에 제한이있는 경우를 제외하고는 프레임이 많을수록 아무 것도 변경되지 않은 가능성이 더 커집니다. 이렇게하면 불필요한 작업을 줄일 수 있습니다.

//Has filter or source image changed? 
// yes, recalculate filter and cache 
// no, render cached image 

마지막으로 LookupOp 구현에 대한 가시성이 있습니까? 무엇을하고 있으며 구현 자체를 작성하여 수집 할 수있는 성능 향상 기능이 있습니까 (최후의 수단이어야 함).