控制C ++ AMP中的索引变量

时间:2012-01-13 16:32:10

标签: c++ multithreading visual-c++ gpu-programming 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;
}

但是,正如您所看到的,这并没有考虑距离矩阵的对称性。当我计算矩阵的矩阵 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语句会不必要地损害性能?我无法想出任何替代方案


顺便说一句,我刚才注意到上面编写的代码在我的机器上不起作用,它的gpu只支持单精度。有什么可以解决这个问题吗?错误信息如下: “runtime_exception:Concurrency ;; parallel_for_each使用所选加速器不支持的功能。 ID3D11Device :: CreateComputeShader:Shader使用当前设备不支持的双精度浮点运算。“

1 个答案:

答案 0 :(得分:2)

我认为你可以消除if条件,如果你只安排你需要的线程数,而不是安排覆盖输出矩阵的整个矩形。您需要的是没有对角线的上三角或下三角,您可以使用算术序列计算。

另一种方法是组织输入数据,使其在两个1D向量中,每个线程将从向量1读取值,然后向量2并计算距离并将其存储在其中一个输入向量中。

最后,出现双精度错误,因为您使用的卡不支持双精度操作。请检查您的卡规格以确认。您可以通过切换到单精度类型(即array_view模板中的“float”)来解决此问题。