B.S*_*.S. 8 c++ optimization static if-statement static-if
我正在测试各种优化的组合,对于这些,我需要一个静态的,如果在描述http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Static-If-I-Had-a-Hammer启用并禁用特定的优化.if(const-expr)并不总是有效,因为某些优化涉及更改数据布局,而这在功能范围内无法完成.
基本上我想要的是这个:
template<bool enable_optimization>
class Algo{
struct Foo{
int a;
if(enable_optimization){
int b;
}
void bar(){
if(enable_optimization){
b = 0;
}
}
};
};
Run Code Online (Sandbox Code Playgroud)
(是的,在我的情况下,从数据布局中删除b的较小内存占用量是相关的.)
目前我正在使用非常糟糕的黑客伪装它.我正在寻找一种更好的方法.
档案啊
#ifndef A_H
#define A_H
template<class enable_optimization>
class Algo;
#include "b.h"
#endif
Run Code Online (Sandbox Code Playgroud)
文件bh(此文件是从Python脚本自动生成的)
#define ENABLE_OPTIMIZATION 0
#include "c.h"
#undef
#define ENABLE_OPTIMIZATION 1
#include "c.h"
#undef
Run Code Online (Sandbox Code Playgroud)
文件ch
template<>
class Algo<ENABLE_OPTIMIZATION>{
struct Foo{
int a;
#if ENABLE_OPTIMIZATION
int b;
#endif
void bar(){
#if ENABLE_OPTIMIZATION
b = 0;
#endif
}
};
};
Run Code Online (Sandbox Code Playgroud)
有谁知道更好的方法吗?从理论上讲,它可以使用模板元编程完成,起初我使用它.至少我使用它的方式是屁股的痛苦,并导致完全不可读和臃肿的代码.使用上面的hack可以显着提高生产力.
编辑:我有几个优化标志,这些互动.
没有理由使用模板使代码变得更加复杂:
template<bool enable_optimization>
class FooOptimized
{
protected:
int b;
void bar_optim()
{
b = 0;
}
};
template<>
class FooOptimized<false>
{
protected:
void bar_optim() { }
};
template<bool enable_optimization>
struct Algo
{
struct Foo : FooOptimized<enable_optimization>
{
int a;
void bar()
{
this->bar_optim();
}
};
};
Run Code Online (Sandbox Code Playgroud)
不需要元编程,只需根据优化是否启用为新类型并将其专门化来区分不同的部分.
因为新类型在它为空时用作基类(即没有FooOptimized::b成员),所以它不会占用空间sizeof(Algo<false>::Foo) == sizeof(int).
(可以随意忽略这个答案的其余部分,它没有直接解决问题,而是建议采用不同的方法进行不同的权衡.是否"更好"与否取决于真实代码的细节,在问题中给出的小例子中没有显示.)
作为一个相关的,但独立的问题上,各部分Algo和Algo::Foo那不取决于优化是否启用仍依赖模板参数,所以虽然你只写这些代码位一次,编译器将产生两套目标代码.根据代码中的工作量以及它的使用方式,您可能会发现将其更改为非模板代码是有利的,即用动态多态替换静态多态.例如,您可以使enable_optimization标志成为运行时构造函数参数而不是模板参数:
struct FooImpl
{
virtual void bar() { }
};
class FooOptimized : FooImpl
{
int b;
void bar()
{
b = 0;
}
};
struct Algo
{
class Foo
{
std::unique_ptr<FooImpl> impl;
public:
explicit
Foo(bool optimize)
: impl(optimize ? new FooOptimized : new FooImpl)
{ }
int a;
void bar()
{
impl->bar();
}
};
};
Run Code Online (Sandbox Code Playgroud)
你必须来分析和测试,以确定虚函数是否有更多的比的代码复制开销少Algo并且Algo::Foo不依赖于模板参数.