私は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;
}
ただし、ご覧のとおり、これは距離行列の対称性を考慮していません。行列iとjのsqrsumを計算するとき、 iと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-conditionはその仕事をすることができますか?それとも、ifステートメントがパフォーマンスを不必要に損なうと思いますか?私はそれに代わるものを思い付くことができませんでした
ところで、上記のコードが私のマシンでは機能しないことに気づきました。そのgpuは単精度しかサポートしていません。その問題を回避するために何かすることはありますか?エラーメッセージは次のとおりです。「runtime_exception:Concurrency ;; parallel_for_eachは、選択したアクセラレータでサポートされていない機能を使用します。ID3D11Device:: CreateComputeShader:Shaderは、現在のデバイスでサポートされていない倍精度浮動小数点演算を使用します。」