2012-01-13 2 views
0

저는 C++ AMP를 사용하기 시작했습니다. 현재 작업하고있는 현재 프로젝트를 사용하기로했습니다. 어떤 시점에서, 나는 내가 가지고있는 벡터에 대한 거리 행렬을 구축하고 난 당신이 볼 수 있듯이,이 계정에 거리의 대칭 속성을 고려하지 않습니다, 그러나이C++ AMP에서 인덱스 변수 제어

unsigned int samplesize=samplelist.size(); 
unsigned int vs = samplelist.front().size(); 

vector<double> samplevec(samplesize*vs); 
vector<double> distancevec(samplesize*samplesize,0); 

it1=samplelist.begin(); 

for(int i=0 ; i<samplesize; ++i){ 
    for(int j = 0 ; j<vs ; ++j){ 
     samplevec[j + i*vs] = (*it1)[j]; 
    } 
    ++it1; 
} 

array_view<const double,2> samplearray(samplesize,vs,samplevec); 
array_view<writeonly<double>,2> distances(samplesize,samplesize,distancevec); 

parallel_for_each(distances.grid, [=](index<2> idx) restrict(direct3d){ 
    double sqrsum=0; 
    double tempd=0; 

    for (unsigned int i=0 ; i<vs ; ++i) 
    { 
     tempd = samplearray(idx.x,i) - samplearray(idx.y,i); 
     sqrsum += tempd*tempd; 
    } 
    distances[idx]=sqrsum; 
} 

에 대한 코드 아래 작성했습니다 행렬. 내가 행렬 내가J의 sqrsum을 계산할 때, 나는 내가J의 순서가 반전 될 때 다시 같은 계산을하고 싶지 않아요. 이것을 달성 할 방법이 있습니까? 나는 다음과 같은 트릭을 함께했다,하지만이 경우 조건이 일을 할 수있는 성능을 크게

for (unsigned int i=0 ; i<vs ; ++i) 
    { 
     if(idx.x<=idx.y){ 
      break; 
     } 

     tempd = samplearray(idx.x,i) - samplearray(idx.y,i); 
     sqrsum += tempd*tempd; 
    } 

을 범프 것 나도 몰라? 또는 if 문이 성능을 불필요하게 손상시킬 것이라고 생각합니까? 난 그냥 위의 작성된 코드는 그 GPU만을 단 정밀도를 지원 내 컴퓨터에 작동하지 않는 것을 발견,


BTW 그것을 (를) 대체 할 수있는 다른 내놓았다 없습니다. 그 문제를 해결하기 위해 할 일이 있습니까? 오류 메시지는 다음과 같습니다 : "runtime_exception : 동시성 ;; parallel_for_each는 선택한 가속기에서 지원하지 않는 기능을 사용합니다. ID3D11Device :: CreateComputeShader : Shader는 현재 장치에서 지원되지 않는 배정도 부동 소수점 연산을 사용합니다."

답변

2

출력 매트릭스를 커버하는 전체 사각형을 스케줄링하는 대신 필요에 따라 많은 스레드만을 스케줄하는 경우 if 조건을 제거 할 수 있다고 생각합니다. 필요한 것은 산술 시퀀스를 사용하여 계산할 수있는 대각선없는 위 또는 아래 삼각형입니다.

입력 데이터를 두 개의 1D 벡터로 구성하고 각 스레드가 벡터 1의 값을 읽은 다음 벡터 2를 읽고 거리를 계산하여 입력 벡터 중 하나에 저장하는 방법이 있습니다.

마지막으로, 사용중인 카드가 배정도 작업을 지원하지 않기 때문에 이중 정밀도 오류가 나타납니다. 카드 사양을 확인하여 확인하십시오. array_view 템플릿에서 단 정밀도 유형, 즉 "float"로 전환하여 문제를 해결할 수 있습니다.

+0

모든 double이 float로 변경되었으므로 다음 오류가 발생합니다. "runtime_exception : 커널을 디스패치하지 못했습니다. ID3D11DeviceContext :: Dispatch : 컴퓨터 쉐이더 유닛의 슬롯 0에있는 쉐이더 리소스 뷰는 구조화 된 버퍼입니다. 셰이더가 실제로 셰이더 코드 브랜칭으로 인해 건너 뛰지 않은 경우와 같이이 불일치는 유효하지 않습니다. " – aristos

+0

BTW가 idx.x, idx.y 표기법을 사용하여 위쪽 삼각형을 지정하는 방법을 찾지 못했습니다. 당신은 정교 할 수 있습니까? – aristos

+0

태그 지정에 문제가 있다고 생각합니다. 또 다른 기회를주는 @SimonWybranski – aristos