각 레이어는 프리미티브 (int 또는 int)의 2D 배열 인 여러 가지 레이어에서 상당히 간단한 함수 집합 (평균, 가중 평균/흐림, n 공백 아래로 이동 등)을 실행해야합니다. 흙손). 입력 값은 최대 8k x 4k이지만 더 자주 2k x 1k 미만입니다. 입력 데이터는 변경 불가능하며 모든 셀을 처리 한 후에 출력으로 대체되고 모든 것이 다시 실행됩니다. 실시간으로 실행될 것으로 기대하지는 않지만 초당 약 10 개의 이미지를 처리해야합니다. 모든 입력 함수는 여러 개의 셀을 샘플링 할 수 있지만 단 하나의 셀에만 쓰고 상태는 유지되지 않습니다 (모든 의도와 목적을 위해 프래그먼트 셰이더).서버 측 이미지 처리
클라이언트 측에서이 작업을 수행하면이 작업을 GPU에 맡기고 초당 수천 번의 반복 작업에도 문제가 없습니다. 그러나 이것은 GPU가없는 서버 (아마 VM)에서 실행해야합니다. 서버는 대개 RH 기반의 Linux가 될 것입니다.하지만이 경우 C 라이브러리를 추가하지 않아도됩니다.
코드가 this gist 인 현재 테스트는 4k x 2k 이미지에서 단일 스레드 인 경우 초당 약 8 개의 이미지가 최대 속도가됩니다. 그것은 수용 가능한 성능을위한 최소한의 것입니다, 그리고 멀티 스레딩은 받아 들일 수 있습니다 (여전히 그것을 테스트합니다). JMH는 제공 : 기본 기능으로
Benchmark Mode Samples Score Score error Units
t.ShaderFunc.testProcess thrpt 40 5.506 0.478 ops/s
t.ShaderFunc.testProcessInline thrpt 40 7.657 0.561 ops/s
t.ShaderFunc.testProcessProc thrpt 40 5.685 0.350 ops/s
을 :
나를 걱정이 내가 처리됩니다 간단한 기능 중 하나로서public int blur(final int[][] data, final int x, final int y) {
float accumulator = 0;
int[] col = data[x];
accumulator += col[y];
if (x > 0) {
accumulator += data[x-1][y] * 0.5f;
}
if (x < data.length - 1) {
accumulator += data[x+1][y] * 0.5f;
}
if (y > 0) {
accumulator += col[y-1] * 0.5f;
}
if (y < col.length - 1) {
accumulator += col[y+1] * 0.5f;
}
return Math.round(accumulator/3f);
}
.
처리 기능이 인터페이스 (Java 8, 잠재적으로 람다) 일 수 있지만 처리 기능이 루프에서 인라인 인 경우 일부 초기 벤치 마크는 대략 30 %의 성능 증가를 나타낼 것을 선호합니다. 루프가 얼마나 단단한 지 감안할 때, 호출 오버 헤드가 문제라고 생각할 수 있습니다.
성능을 크게 변경시키는 라이브러리, 내장 또는 기타 기술이 있습니까? 이 코드를 벡터화하는 데 사용할 수있는 기법이 있습니까 (함수가 작동하는 방식을 고려할 때 확실하지는 않습니다).
업데이트 : Stuart Marks의 변경 사항을 통합하고 Aleksey Shipilev의 제안과 함께 실행 한 결과는 매우 달랐습니다. 이것은 내 작업 기계 (VMware Workstation 10의 CentOS 6.5 VM에서 i7-3840QM이있는 Lenovo W530)와 내 가정용 컴퓨터 (Win 8.1의 Surface Pro 2)에 대한 것입니다. 이 잘 내가 기대 한 것 이상으로, 훌륭한 성능이다
Benchmark Mode Samples Score Score error Units
c.s.q.ShaderFunc.testProcess thrpt 40 40.890 5.772 ops/s
c.s.q.ShaderFunc.testProcessInline thrpt 40 44.032 2.389 ops/s
c.s.q.ShaderFunc.testProcessProc thrpt 40 44.378 2.153 ops/s
: 제안 된 변경
Benchmark Mode Samples Score Score error Units
c.s.q.ShaderFunc.testProcess thrpt 40 9.098 0.054 ops/s
c.s.q.ShaderFunc.testProcessInline thrpt 40 11.337 1.603 ops/s
c.s.q.ShaderFunc.testProcessProc thrpt 40 11.706 0.105 ops/s
(code here) : 나는 업데이 트 (11)
원래 취지 결과를 JDK 1.8를 사용하고 있습니다 .
업데이트 2 : 원하는 코드와 좀 더 가깝게 코드를 변경하면 람다 또는 클래스를 호출하는 오버 헤드가 반환 된 것 같습니다. 코드가 변경되어 클린 상태가되고, 벤치 마크를 some JMH recommendations을 기준으로 리팩토링했습니다.this gist의 코드를 기반으로, 결과는 다음과 같습니다
Benchmark Mode Samples Score Score error Units
c.s.q.ShaderBench.testProcessInline thrpt 200 40.685 0.224 ops/s
c.s.q.ShaderBench.testProcessLambda thrpt 200 16.077 0.113 ops/s
c.s.q.ShaderBench.testProcessProc thrpt 200 23.827 0.088 ops/s
을 가장 저렴한 디지털 오션 노드에서 :
Benchmark Mode Samples Score Score error Units
c.s.q.ShaderBench.testProcessInline thrpt 200 24.425 0.506 ops/s
c.s.q.ShaderBench.testProcessLambda thrpt 200 9.643 0.140 ops/s
c.s.q.ShaderBench.testProcessProc thrpt 200 13.733 0.134 ops/s
서버 유형의 VM에
Benchmark Mode Samples Score Score error Units
c.s.q.ShaderBench.testProcessInline thrpt 200 40.860 0.184 ops/s
c.s.q.ShaderBench.testProcessLambda thrpt 200 22.603 0.159 ops/s
c.s.q.ShaderBench.testProcessProc thrpt 200 22.792 0.117 ops/s
내가 사용할 계획
허용되는 모든 성능 (제 작업 기계 및 전용 VM에서 꽤 환상적인 성능). 나는 그 전화가 왜 그렇게 큰 오버 헤드를 가지며 그것을 최적화하기 위해 할 수 있는지 알아내는 것에 관심이있다. 현재 다른 매개 변수 집합을 실험하고 a more specific question 게시했습니다.
멀티 스레딩은 성능을 향상시킬 수 있습니다. – vandale
@vandale 거의 확실합니다. 최소한 각 이미지는 별도의 스레드에서 실행될 수 있습니다. 나는 이미지 처리 라이브러리의 방향을 좀 더 찾고있다. 코드를 유행에 따라 벡터화하거나, 병렬 확장을하거나, 그 라인을 따라 무엇인가를 찾고있다. – ssube