简体   繁体   English

C ++这是一种微优化形式

[英]C++ Is this a form of micro optimization

Is this micro-optimization, or is it optimization at all? 这是微优化,还是优化呢?

void Renderer::SetCamera(FLOAT x, FLOAT y, FLOAT z) {
    // Checking for zero before doing addition?
    if (x != 0) camX += x;
    if (y != 0) camY += y;
    if (z != 0) camZ += z;

    // Checking if any of the three variables are not zero, and performing the code below.
    if (x != 0 | y != 0 | z != 0) {
        D3DXMatrixTranslation(&w, camX, camY, camZ);
    }
}

Would running a for.. loop with the condition having vector.size() force the application to recount the elements in the vector on each loop? 使用带有vector.size()的条件运行for循环会强制应用程序重新计算每个循环中向量中的元素吗?

std::vector<UINT> vect;

INT vectorSize = vect.size();
for (INT Index = 0; Index < vectorSize; Index++) {
// Do vector processing
}

// versus:

std::vector<UINT> vect;

for (INT Index = 0; Index < vect.size(); Index++) {
// Do vector processing
}

I'm using Visual Studio and as for the second question, it seems like something a compiler could optimize, but I'm just not sure on that. 我正在使用Visual Studio,至于第二个问题,它似乎是编译器可以优化的东西,但我只是不确定。

Depending on the implementation of vector, the compiler may or may not understand that size is not changed. 根据向量的实现,编译器可能会或可能不会理解大小未更改。 After all, you call different vector functions inside the loop, any of which might change size. 毕竟,你在循环中调用不同的向量函数,其中任何一个都可能改变大小。

Since vector is a template, then the compiler knows everything about it, so if it works really hard, it could understand that size doesn't change, but that's probably too much work. 由于vector是一个模板,然后编译器知道它的一切,所以如果它真的很难,它可以理解大小不会改变,但这可能太多了。

Often, you would want to write like this: 通常,你会想这样写:

for (size_t i = 0, size = vect.size(); i < size; ++i)
    ...

While we're at it, a similar approach is used with iterators: 虽然我们正在使用它,但迭代器使用了类似的方法:

for (list<int>::iterator i = lst.begin(), end = lst.end(); i != end; ++i)
    ...

Edit: I missed the first part: 编辑:我错过了第一部分:

Is this optimization? 这是优化吗?

if (x != 0) camX += x;
if (y != 0) camY += y;
if (z != 0) camZ += z;

No. First of all, even if they were int, it wouldn't be optimization since checking and branching when the values are probably most of the times not zero is more work. 首先,即使它们是int,也不是优化,因为检查和分支时值大概是大多数时间而不是零是更多的工作。

Second and more importantly, they are float. 其次,更重要的是,它们是浮动的。 This means that besides the fact that you shouldn't directly compare them to 0 , they are basically almost never exactly equal to 0. So the if s are 99.9999% true. 这意味着除了你不应该直接将它们与0进行比较这一事实外,它们基本上几乎不会完全等于0.所以if为99.9999%为真。

Same thing applies to this: 同样的事情适用于此:

if (x != 0 | y != 0 | z != 0)

In this case however, since matrix translation could be costly, you could do: 但是,在这种情况下,由于矩阵转换成本很高,您可以:

#define EPS 1e-6 /* epsilon */
if (x > EPS || x < -EPS || y > EPS || y < -EPS || z > EPS || z < -EPS)

and now yes, comparing to a matrix multiplication, this is probably an optimization. 现在是的,与矩阵乘法相比,这可能是一种优化。

Note also that I used || 另请注意,我使用了|| which gets short-circuited if for example right from the beginning x > EPS is true (it won't calculate the rest), but with | 如果例如从开始x > EPS是真的(它将不计算其余的),它会被短路,但是| that won't happen. 这不会发生。

I suspect that on many architectures the first three lines are an anti-optimization because they may introduce a floating point compare and then branch which can be slower than just always doing the addition (even if it's floating point). 我怀疑在许多架构上,前三行都是反优化,因为它们可能会引入浮点比较然后分支,这可能比仅总是进行加法更慢(即使它是浮点数)。

On the other hand making sure that at least one component is non-zero before doing the transformation seems sound. 另一方面,在进行转换之前确保至少一个组件非零是合理的。

For your second case, size has to be constant time and will almost certainly be inlined out to a direct access to the vector 's size. 对于你的第二种情况, size必须是恒定的时间,并且几乎肯定会被内联到直接访问vector的大小。 It's most likely fully optimizable. 它很可能完全可以优化。 That said, sometimes it can make the code/loop easier to read by saving the size off because that clearly shows you are asserting the size won't change during the loop. 也就是说,有时它可以通过保存大小来使代码/循环更容易读取,因为这清楚地表明你断言大小在循环期间不会改变。

Firstly, Regarding the vector.size() , see this SO question . 首先,关于vector.size() ,请参阅此SO问题 On a side note, I haven't seen an implementation where std::vector::size() isn't O(1). 另外,我没有看到std::vector::size()不是O(1)的实现。

if (x != 0) camX += x; this cmp and consequent jne however is going to be slower than simply adding the variable x no matter what. 然而,这个cmp和随之而来的jne将比简单地添加变量x更慢。 Edit: Unless you expect well over 50 % cache misses on camX 编辑:除非你期望在camX上有超过50%的缓存未camX

The first one is probably a pessimisation, the check for 0 is probably slower than the addition. 第一个可能是悲观,0的检查可能比添加慢。 On top of that, in the check before the call to D3DXMatrixTranslation , you use | 最重要的是,在调用D3DXMatrixTranslation之前的检查中,使用| instead of the short-circuiting logical or || 而不是短路逻辑或|| . Since the check before the function call is probably a time-saver (or even semantically necessary), wrap the entire code in that check, 由于函数调用之前的检查可能节省了时间(甚至在语义上是必需的),因此将整个代码包装在该检查中,

void Renderer::SetCamera(FLOAT x, FLOAT y, FLOAT z) {

    if (x != 0 || y != 0 || z != 0) {
        camX += x;
        camY += y;
        camZ += z;
        D3DXMatrixTranslation(&w, camX, camY, camZ);
    }
}

if all of x , y and z are zero, nothing need be done, otherwise, do all. 如果xyz都为零,则不需要做任何事情,否则,全部做。

For the second, the compiler can hoist the vector.size() outside the loop if it can determine that the size doesn't change while the loop runs. 对于第二种情况,编译器可以在循环外提升vector.size() ,如果它可以确定在循环运行时大小不会改变。 If the compiler cannot determine that, it must not hoist the size() computation outside the loop. 如果编译器无法确定,则不得在循环外提升size()计算。

Doing that yourself when you know that the size doesn't change is good practice. 当你知道尺寸没有改变时,自己动手做是很好的做法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM