微优化:使用局部变量与.class成员进行迭代
Microoptimization: iterating with local variable vs. class member
我想如果我将迭代变量声明为类成员一次,我会节省一些时间:
struct Foo {
int i;
void method1() {
for(i=0; i<A; ++i) ...
}
void method2() {
for(i=0; i<B; ++i) ...
}
} foo;
但是,这似乎快了 20%
struct Foo {
void method1() {
for(int i=0; i<A; ++i) ...
}
void method2() {
for(int i=0; i<B; ++i) ...
}
} foo;
在此代码中
void loop() { // Arduino loops
foo.method1();
foo.method2();
}
您能解释一下性能差异吗?
(我需要在Arduino上运行许多简单的平行"过程",其中这种微优化会有所不同。
当你在循环中声明循环变量时,它的作用域非常窄。编译器可以自由地始终将其保存在寄存器中,因此它甚至一次都不会提交到内存中。
将循环变量声明为实例变量时,编译器没有这种灵活性。它必须将变量保留在内存中,以防某些方法想要检查其状态。例如,如果您在第一个代码示例中执行此操作
void method2() {
for(i=0; i<B; ++i) { method3(); }
}
void method3() {
printf("%dn", i);
}
method3
中的i
值必须随着循环的进行而更改。编译器无法将其所有副作用提交到内存中。此外,它不能假设当您从method3
回来时i
保持不变,这进一步增加了内存访问次数。
处理内存中的更新比对基于寄存器的变量执行更新需要更多的 CPU 周期。这就是为什么将循环变量的范围缩小到循环级别始终是一个好主意。
您能解释一下性能差异吗?
对于这种性能差异,我能想到的最合理的解释是:
数据成员i
是在全局内存上声明的,全局内存不能一直保存在寄存器中,因此对它的操作会比对循环变量的操作慢得多i
由于范围非常广泛(数据成员i
必须满足类的所有成员函数)。
@DarioOO补充说:
此外,编译器不能自由地将其临时存储在 注册,因为
method3()
可能会引发异常离开对象 处于不需要的状态(因为理论上没有人阻止您 写int k=this->i; for(k=0;k<A;k++)method3(); this->i=k;
.该代码 几乎和局部变量一样快,但你必须保持 帐户当method3()
抛出时(我相信当有保证时 不抛出编译器将优化它与-O3
或-O4
已验证)
- "Class1"类"Class2"对象作为私有数据成员。如何通过"Class 2"函数引用"Class1"对象?
- 错误:'class std::unique_ptr<std::set<long unsigned int> >'没有名为 'size' 的成员
- 如何从类成员函数返回指针,例如 size_t * class :: function(); 并使用类析构函数 ~size
- 是否可以将 std::unordered_map<Class, Class> 作为 Class 的成员?
- Visual Class 在 DLL 中的成员函数中返回自身C++
- 如何将带有 std::vector 成员的类移动到<class>另一个向量<class>中?
- 模板类静态成员变量在使用'extern template class'语法时的特殊化
- 向量<Class>没有成员"函数"
- 非静态成员函数的使用无效(while loop/no class/wget popen)
- 头文件中是否定义了一个很长的Class函数成员
- 关于C++中Class的私有成员
- "class::data member is private"错误,但我正在使用成员函数对其进行操作?
- 错误:'class std::stack<>'没有名为 'pop_back' 的成员
- 为什么constexpr静态成员(类型为class)需要定义
- 错误:'class TermPaper'没有命名的成员
- 如何修复'class android::Surface'没有名为"setDirtyRect"的成员?
- 'class Poco::XML::Element'没有名为'getNodeByPath'的成员
- 微优化:使用局部变量与.class成员进行迭代
- 智能感知说错误:成员"Class::field"无法访问,但它仍然有效?为什么?
- 类没有成员"Class"