我刚刚开始尝试使用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 时,我不希望在 i 和<的顺序时再次执行相同的计算em> 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条件可以完成这项工作吗?或者您认为if语句会不必要地损害性能?我无法想出任何替代方案
答案 0 :(得分:2)
我认为你可以消除if条件,如果你只安排你需要的线程数,而不是安排覆盖输出矩阵的整个矩形。您需要的是没有对角线的上三角或下三角,您可以使用算术序列计算。
另一种方法是组织输入数据,使其在两个1D向量中,每个线程将从向量1读取值,然后向量2并计算距离并将其存储在其中一个输入向量中。
最后,出现双精度错误,因为您使用的卡不支持双精度操作。请检查您的卡规格以确认。您可以通过切换到单精度类型(即array_view模板中的“float”)来解决此问题。