我可以优化code,有3环和4 IFS?code、IFS

2023-09-11 05:24:58 作者:青春之帆由我掌舵

我又交

here在那里我问如何在三维空间中的26邻居立方体素的节点。我有一个很好的答案,并付诸实施。

要我加了一些MIN MAX位置检查。

如果使用我想知道是否有办法,的关系,以3环和4,以提高该code的执行时间。我读的时候使用whil​​e循环更快另一篇文章......但它是在一个岗位不特定的语言。

这是真的吗?如果是的话,可以ü请帮助我在我的code,因为我的运气经验? 有没有一种方法可以递归实现这一点的方式,将使其更快?

这是我的code:

  ...
的std ::矢量<平面> Create26Neighbor(位置somePos,双甲阶酚醛树脂)
{
    的std ::矢量<平面> vect1;
    波什m_MinPos(0.0,0.0,0.0);
    波什m_MaxPos(5.0,4.0,5.0);

    为(双的dz = somePos.m_pPos [2]  - 甲阶; dz的&其中; = somePos.m_pPos [2] +甲阶; DZ + =甲阶)
    {
    如果(DZ> m_MinPos.m_pPos [2]&安培;&安培; dz的&其中; m_MaxPos.m_pPos [2])
    {
    对于(双DY = someCPos.m_pPos [1]  - 甲阶段酚醛树脂; DY< = someCPos.m_pPos [1] +甲阶酚醛树脂; DY + =甲阶酚醛树脂)
    {
    如果(镝> m_MinPos.m_pPos [1]&安培;&安培;镝&其中; m_MaxPos.m_pPos [1])
    {
    对于(双DX = somePos.m_pPos [0]  - 甲阶酚醛树脂; DX< = somePos.m_pPos [0] +甲阶酚醛树脂; DX + =甲阶酚醛树脂)
    {
    如果(DX> m_MinPos.m_pPos [0]&安培;&安培; DX&其中; m_MaxPos.m_pPos [0])
    {
    //所有27
    如果((DX!= somePos.m_pPos [0])||(DY!= somePos.m_pPos [1])||(DZ!= somePos.m_pPos [2]))
    {
    波什tempPos(DX,DY,DZ);
    vect1.push_back(tempPos);
    }
    }
    }
    }
    }
    }
    }
    返回vect1;
}
....
 
0.4 edit code 可选VSCode来做代码编辑超好用

解决方案

首先,摆脱if语句的。没有必要对它们。你可以将它们合并到循环条件。其次,避免重新计算循环条件每次迭代。是的,编译器可以优化它拿走,但它通常是非常保守的浮点优化(它可能把从内存中读出不同于那些从寄存器读取FP值,这意味着它的不能的消除环路条件阵列查找),所以它往往是最好的做手工,甚至简单的优化:

 的std ::矢量<平面> Create26Neighbor(位置somePos,双甲阶酚醛树脂)
{
    的std ::矢量<平面> vect1(27); //初始化向量具有正确大小。
    波什m_MinPos(0.0,0.0,0.0);
    波什m_MaxPos(5.0,4.0,5.0);

    双minz =标准::最大值(somePos.m_pPos [2]  - 甲阶,m_MinPos.m_pPos [2]);
    双maxz =标准::分(somePos.m_pPos [2] +甲阶酚醛树脂,m_MaxPos.m_pPos [2];
    INT I = 0;
    对于(双DZ =分钟; DZ< = MAX; DZ + =甲阶酚醛树脂)
    {
        双MINY =标准::最大值(somePos.m_pPos [1]  - 甲阶,m_MinPos.m_pPos [1]);
        双MAXY =标准::分钟(somePos.m_pPos [1] +甲阶,m_MaxPos.m_pPos [1];
        对于(双DY = MINY;颐和LT = MAXY; DY + =甲阶酚醛树脂)
        {
            双疯丫头=的std :: MAX(somePos.m_pPos [0]  - 甲阶酚醛树脂,m_MinPos.m_pPos [0]);
            双MAXX =标准::分(somePos.m_pPos [0] +甲阶酚醛树脂,m_MaxPos.m_pPos [0];

            对于(双DX =疯丫头; DX< = MAXX; DX + =甲阶酚醛树脂)
            {
                ++我;
                //如果我们不是在市中心,就用'我'为指标。否则,使用I + 1
                INT IDX =(DX!= somePos.m_pPos [0] || DY!= somePos.m_pPos [1] ||的dz!= somePos.m_pPos [2])? I:I + 1;
                VEC 1 [IDX] =波什(DX,DY,DZ); //构造波什就在现场,*力量*为您节省副本,相比initilizing它,把它作为一个局部变量,然后将其复制到载体。
              }
        }
    }
    返回vect1;
}
 

最后一点,我会考虑看是内心的if语句。在紧密循环分行可能比你想象的更昂贵。我能想到的一些方法来消除它:

当我勾勒了code,?:运算符可以被哄骗入计算的中心值不同的矢量指数(所以它的写入下一个矢量元素,因此被覆盖再下一次迭代)。这就消除了在分支,但可以是或可以不是更快的整体。 分裂的循环,所以你有单独的循环之前和甲阶酚醛树脂的价值之后。这样做有点别扭,有一大堆的小环,并且可以是低效率的整体。但是,这将消除内if语句,所以它也可能会更快。 允许中心点被添加到向量,要么忽略它之后,或在循环之后将其删除(这会是一个比较昂贵的操作,可能会或可能不会得到回报。如果你也许会更便宜用它代替矢量一个deque。

和确保编译器将展开内部循环。手动展开它可能帮助了。

最后,很多取决于波什的定义。

请注意,大部分是我建议由合格也未必会更快,但是......。你必须不断的轮廓和基准每次改变你做,保证你实际​​上提高了性能。

根据多远你愿意去,你可以合并一切成一个循环(整数上运行),只是计算名次坐标上的每个迭代中飞行。

i made another post

here where I asked how to create the 26 neighbors of a cubic-voxel-node in 3-d space. I got a very good answer and implemented it.

To that I added some MIN MAX Position checking.

I would like to know if there is way, in relationship to the 3 for loops and 4 if used, to improve the execution time of this code. I have read in another post sth that when using while loops is faster but it was in a post not language specific.

Is this true? If yes, could u please help me to this in my code because i luck experience? Is there a way to implement this recursively in a way that will make it faster?

here is my code:

...
std::vector<Pos> Create26Neighbor(Pos somePos, double resol) 
{
    std::vector <Pos> vect1;
    Pos  m_MinPos(0.0,0.0,0.0);
    Pos  m_MaxPos(5.0,4.0,5.0);

    for (double dz = somePos.m_pPos[2] - resol; dz <= somePos.m_pPos[2] + resol; dz+=resol)
    {
    	if (dz>m_MinPos.m_pPos[2] && dz<m_MaxPos.m_pPos[2])
    	{
    		for (double dy = someCPos.m_pPos[1] - resol; dy <= someCPos.m_pPos[1] + resol; dy+=resol)
    		{
    			if (dy>m_MinPos.m_pPos[1] && dy<m_MaxPos.m_pPos[1])
    			{
    				for (double dx = somePos.m_pPos[0] - resol; dx <= somePos.m_pPos[0] + resol; dx+=resol)
    				{
    					if (dx>m_MinPos.m_pPos[0] && dx<m_MaxPos.m_pPos[0])
    					{
    						// all 27
    						if ((dx != somePos.m_pPos[0]) || (dy != somePos.m_pPos[1]) || (dz != somePos.m_pPos[2]))
    						{
    							Pos tempPos(dx,dy,dz);
    							vect1.push_back(tempPos);
    						}
    					}
    				}
    			}
    		}
    	}
    }
    return vect1;
}
....

解决方案

First, get rid of the if statements. There's no need for them. You can merge them into the loop condition. Second, avoid recomputing the loop condition every iteration. Yes, the compiler may optimize it away, but it's generally very conservative with floating-point optimizations (and it may treat fp values read from memory differently from ones read from a register, which means it can't eliminate your array lookups from the loop conditions), so it's often best to do even simple optimizations manually:

std::vector<Pos> Create26Neighbor(Pos somePos, double resol) 
{
    std::vector <Pos> vect1(27); // Initialize the vector with the correct size.
    Pos  m_MinPos(0.0,0.0,0.0);
    Pos  m_MaxPos(5.0,4.0,5.0);

    double minz = std::max(somePos.m_pPos[2] - resol, m_MinPos.m_pPos[2]);
    double maxz = std::min(somePos.m_pPos[2] + resol, m_MaxPos.m_pPos[2];
    int i = 0;
    for (double dz = min; dz <= max; dz+=resol)
    {
        double miny = std::max(somePos.m_pPos[1] - resol, m_MinPos.m_pPos[1]);
        double maxy = std::min(somePos.m_pPos[1] + resol, m_MaxPos.m_pPos[1];
        for (double dy = miny; dy <= maxy; dy+=resol)
        {
            double minx = std::max(somePos.m_pPos[0] - resol, m_MinPos.m_pPos[0]);
            double maxx = std::min(somePos.m_pPos[0] + resol, m_MaxPos.m_pPos[0];

            for (double dx = minx; dx <= maxx; dx+=resol)
            {
                ++i;
                // If we're not at the center, just use 'i' as index. Otherwise use i+1
                int idx = (dx != somePos.m_pPos[0] || dy != somePos.m_pPos[1] || dz != somePos.m_pPos[2]) ? i : i+1;
                vec1[idx] = Pos(dx, dy, dz); // Construct Pos on the spot, *might* save you a copy, compared to initilizing it, storing it as a local variable, and then copying it into the vector.
              }
        }
    }
    return vect1;
}

The last point I'd consider looking at is the inner if-statement. Branches in a tight loop can be more costly than you might expect. I can think of a number of ways to eliminate it:

As I sketched in the code, the ?: operator could be coaxed into calculating a different vector index for the center value (so it's written to the next vector element, and so gets overwritten again next iteration). This would eliminate the branch, but may or may not be faster overall. Split up the loops so you have separate loops before and after the 'resol' value. That gets a bit awkward, with a whole lot of smaller loops, and may be less efficient overall. But it would eliminate the inner if-statement, so it may also be faster. Allow the center point to be added to the vector, and either ignore it afterwards, or remove it after the loops (that'd be a somewhat expensive operation, and may or may not pay off. It may be cheaper if you use a deque instead of vector.

And make sure the compiler unrolls the inner loop. Manually unrolling it may help too.

Finally, a lot depends on how Pos is defined.

Note that most of what I suggested is qualified by "it may not be faster, but...". You have to constantly profile and benchmark every change you make, to ensure you're actually improving performance.

Depending on how far you're willing to go, you may be able to merge everything into one loop (running on integers) and just compute the Pos coordinates on the fly in each iteration.