Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;这是一种微观优化吗_C++_Micro Optimization - Fatal编程技术网

C++ C++;这是一种微观优化吗

C++ C++;这是一种微观优化吗,c++,micro-optimization,C++,Micro Optimization,这是微观优化,还是根本就是优化 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

这是微观优化,还是根本就是优化

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);
    }
}
你会为……而跑吗。。条件为vector.size()的循环强制应用程序在每个循环中重新计算向量中的元素

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
}
std::vector-vect;
INT vectorSize=vect.size();
对于(INT Index=0;Index

我使用的是Visual Studio,至于第二个问题,编译器似乎可以对其进行优化,但是我不确定。我怀疑在许多体系结构上,前三行是反优化的,因为它们可能会引入浮点比较,然后进行分支,这比总是进行加法(即使是浮点)要慢

另一方面,在进行转换之前确保至少一个组件为非零似乎是合理的


对于第二种情况,
size
必须是常数时间,并且几乎肯定会内联到直接访问
向量的size。它很可能是完全可优化的。这就是说,有时它可以通过保存大小使代码/循环更容易阅读,因为这清楚地表明您正在断言大小在循环期间不会改变。

取决于向量的实现,编译器可能理解大小没有改变,也可能不理解大小没有改变。毕竟,在循环中调用不同的向量函数,其中任何一个都可能改变大小

因为vector是一个模板,所以编译器知道关于它的一切,所以如果它工作非常努力,它可以理解大小不会改变,但这可能是太多的工作了

通常,您会希望这样写:

for (size_t i = 0, size = vect.size(); i < size; ++i)
    ...
不。首先,即使它们是int,也不会是优化,因为在大多数情况下,当值可能不是零时,检查和分支需要更多的工作

第二,也是更重要的一点,它们是浮动的。这意味着,除了这一事实,它们基本上永远不会完全等于0。因此,
if
s的正确率为99.9999%

同样的道理也适用于此:

if (x != 0 | y != 0 | z != 0)
但是,在这种情况下,由于矩阵转换可能会很昂贵,您可以执行以下操作:

#define EPS 1e-6 /* epsilon */
if (x > EPS || x < -EPS || y > EPS || y < -EPS || z > EPS || z < -EPS)
#定义EPS 1e-6/*epsilon*/
如果(x>EPS | | x<-EPS | y>EPS | y<-EPS | z>EPS | z<-EPS)
现在是的,和矩阵乘法相比,这可能是一个优化


还要注意的是,我使用了
|
,例如,如果从一开始
x>EPS
为真(它不会计算其余的),它就会短路,但是使用
|
则不会发生短路。

首先,关于
vector.size()
,请参阅 . 另一方面,我还没有看到
std::vector::size()
不是O(1)的实现


如果(x!=0)camX+=x
这个
cmp
和随后的
jne
无论如何都要比简单地添加变量
x
慢。编辑:除非您预期在
camX上的缓存未命中率远远超过50%

第一个可能是悲观的,否则检查0可能比添加慢。最重要的是,在调用
d3dxmatrixtransation
之前的检查中,使用
而不是短路逻辑或
|
。由于函数调用之前的检查可能会节省时间(甚至在语义上是必要的),因此将整个代码包装在该检查中

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);
    }
}
如果
x
y
z
全部为零,则无需执行任何操作,否则,全部执行

对于第二种情况,如果编译器能够确定循环运行时大小没有改变,那么它可以将
vector.size()
提升到循环外部。如果编译器无法确定这一点,则不能将
size()
计算提升到循环之外


当您知道大小没有变化时,您自己这样做是一种良好的做法。

如果值在大多数情况下为
int
且为零,是否仍会适得其反?我的意思是,检查和分支似乎并不比只加零快。@zakinster,如果它们在大多数时候都是
int
和零,那就取决于架构了。我同意你的想法,很可能只是继续添加它会更快,但你永远不知道所有(奇怪的)架构。即使它是
int
并且大部分时间为零,只有当
camX
上有接近100%的缓存读取未命中时,它才会更快@zakinster@zakinster:一般来说,这会适得其反,或者至少没有什么帮助。如果编译器足够聪明,它将把代码翻译成
camX+=x@zakinster:我很确定比较和分支通常比较慢,至少在x86-{32,64}上是这样(假设它没有以某种方式优化)。分支预测没有机会发挥作用,因此阅读
cam?
必须花费相当大的成本才能使分支有价值。我非常喜欢你的答案。悲观是我不得不在字典里加上的一个新词我真的很喜欢。
#define EPS 1e-6 /* epsilon */
if (x > EPS || x < -EPS || y > EPS || y < -EPS || z > EPS || z < -EPS)
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);
    }
}