【问题标题】:OpenCL RK4 Integration on GPUGPU 上的 OpenCL RK4 集成
【发布时间】:2023-04-01 01:00:01
【问题描述】:

当使用 OpenCL 并行化积分器时 - 将整个循环放在内核中是不好的做法吗?

我正在尝试将我用 C++ 编写的 RK4 集成器移动到 OpenCL 中,以便我可以在 GPU 上运行这些操作 - 目前它使用 OpenMP。

我需要运行 1000 万次以上的独立集成运行,每次运行大约有 700 次循环迭代。我目前已将带有停止条件的循环写入内核,但它的性能不如我预期的那样好。

当前 CL 内核 sn-p:

`
while (inPos.z > -1.0f){
        cnt++;
        //Eval 1

        //Euler Velocity
        vel1 = inVel + (inAcc * 0.0f);
        //Euler Position
        pos1 = inPos + (vel1 * 0.0f) + ((inAcc * 0.0f)*0.5f);

        //Drag and accels
        combVel = sqrt(pow(vel1.x, 2)+pow(vel1.y, 2)+pow(vel1.z, 2));
        //motionUtils::drag(netForce, combVel, mortSigma, outPos.z);
        dragForce = mortSigma*1.225f*pow(combVel, 2);
        //Normalise vector
        normVel = vel1 / combVel;
        //Drag Components
        drag = (normVel * dragForce)*-1.0f;
        //Add Gravity force
        drag.z+=((mortMass*9.801f)*-1.0f);
        //Acceleration components
        acc1 = drag/mortMass;

        ...

        //Taylor Expansion
        tayVel = (vel1+((vel2+vel3)*2.0f)+vel4) * (1.0f/6.0f);
        inAcc = (acc1+((acc2+acc3)*2.0f)+acc4) * (1.0f/6.0f);
        tayPos = (pos1+((pos2+pos3)*2.0f)+pos4) * (1.0f/6.0f);

        //Swap ready for next iteration
        inPos = inPos + (tayVel * timeStep);
        inVel = inVel + (inAcc * timeStep);

` 任何想法/建议,非常感谢。

【问题讨论】:

    标签: c++ opencl integration gpu physics


    【解决方案1】:

    尝试更快(但不太精确)的慢速函数版本:

    sqrt(pow(vel1.x, 2)+pow(vel1.y, 2)+pow(vel1.z, 2))
    

    native_rsqrt(vel1.x*vel1.x+vel1.y*vel1.y+vel1.z*vel1.z)
    

     normVel = vel1 / combVel;
    

     normVel = vel1 * combVel;
    

     dragForce = mortSigma*1.225f*pow(combVel, 2);
    

     dragForce = mortSigma*1.225f*(combVel*combVel);
    

        drag = (normVel * dragForce)*-1.0f;
        //Add Gravity force
        drag.z+=((mortMass*9.801f)*-1.0f);
    

        drag = -normVel * dragForce;
        //Add Gravity force
        drag.z-=mortMass*9.801f;
    

        tayVel = (vel1+((vel2+vel3)*2.0f)+vel4) * (1.0f/6.0f);
        inAcc = (acc1+((acc2+acc3)*2.0f)+acc4) * (1.0f/6.0f);
        tayPos = (pos1+((pos2+pos3)*2.0f)+pos4) * (1.0f/6.0f);
    

        tayVel = (vel1+((vel2+vel3)*2.0f)+vel4) * (0.166666f);
        inAcc = (acc1+((acc2+acc3)*2.0f)+acc4) * (0.166666f);
        tayPos = (pos1+((pos2+pos3)*2.0f)+pos4) * (0.166666f);
    

    如果您使用的变量太多,请尝试将本地工作组大小从 256 减少到 128 或 64,如果它们没有在循环外使用,请将它们的声明放入循环中,以便可以同时发出更多线程。

    【讨论】:

    • 欢迎您,您也可以从编译器字符串中启用快速放松的数学选项。
    猜你喜欢
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    • 2015-06-04
    • 2010-12-12
    • 2013-12-03
    • 2018-05-08
    相关资源
    最近更新 更多