要求编译器内联我的 class 并应用通常的优化
Asking compiler to inline my class and apply usual optimizations
假设我有几个对特定数据结构进行运算的相同算法的变体。算法很关键,需要尽可能的高效。
我可以:
通过手动优化将数据结构操纵器复制粘贴到算法的每个变体中。算法足够小,以后不会变,所以其实还是有些可行性的。示例:
int buf[0x100]; // I know it's going to be 0x100, so...
for (...) {
buf[i & 0xFF] // I can use something like this
//buf[i % 0x100] // rather than this.
}
哎呀,我什至不需要做那个 & 0xFF
事情,因为每个编译器都会为我计算出来并将其计算为 and eax, 0xFF
.
将数据结构与所有可能的操作作为一个单独的 class 来实现。现在看起来像这样:
class Buffer {
public:
void operation1(int i) { return buf[i % buf.size()]; }
void operation2() { ... }
private:
std::vector<int> buf;
};
及以后:
Buffer b(0x100);
for (...)
b.operation1(i);
这就是我所说的可读代码,更重要的是,可重用代码!不用说了,我也想用
但是现在我不能做前面的优化,因为我不知道buf的大小,编译器也不知道。 此外 对于这个变体,我面临着函数调用形式的惩罚,其中包括解析 class member/methods,操纵堆栈,yada yada ...
当我对第二个解决方案进行基准测试时,它慢了 20%,所以我的程序需要 10 分钟 运行 而不是 8 分钟。如果我 可以告诉 C++,则可以避免 2 分钟的惩罚编译器完全内联 Buffer
并应用常规优化.
是否有任何技术可以让我做到这一点(模板、constexpr
s,任何真正的东西),或者我是否被迫 "unroll" 手动编写代码?
(编译器特定的解决方案将是最后的手段。)
您使用运行时大小 std::vector
不必要地向编译器隐藏了大小信息。像
template <std::size_t len>
class Buffer {
public:
void operation1(int i) { return buf[i % buf.size()]; }
void operation2() { ... }
private:
std::array<int, len> buf;
};
应该向优化器提供优化所需的信息,就像在 "raw array in function" 情况下一样。
假设我有几个对特定数据结构进行运算的相同算法的变体。算法很关键,需要尽可能的高效。
我可以:
通过手动优化将数据结构操纵器复制粘贴到算法的每个变体中。算法足够小,以后不会变,所以其实还是有些可行性的。示例:
int buf[0x100]; // I know it's going to be 0x100, so... for (...) { buf[i & 0xFF] // I can use something like this //buf[i % 0x100] // rather than this. }
哎呀,我什至不需要做那个
& 0xFF
事情,因为每个编译器都会为我计算出来并将其计算为and eax, 0xFF
.将数据结构与所有可能的操作作为一个单独的 class 来实现。现在看起来像这样:
class Buffer { public: void operation1(int i) { return buf[i % buf.size()]; } void operation2() { ... } private: std::vector<int> buf; };
及以后:
Buffer b(0x100); for (...) b.operation1(i);
这就是我所说的可读代码,更重要的是,可重用代码!不用说了,我也想用
但是现在我不能做前面的优化,因为我不知道buf的大小,编译器也不知道。 此外 对于这个变体,我面临着函数调用形式的惩罚,其中包括解析 class member/methods,操纵堆栈,yada yada ...
当我对第二个解决方案进行基准测试时,它慢了 20%,所以我的程序需要 10 分钟 运行 而不是 8 分钟。如果我 可以告诉 C++,则可以避免 2 分钟的惩罚编译器完全内联 Buffer
并应用常规优化.
是否有任何技术可以让我做到这一点(模板、constexpr
s,任何真正的东西),或者我是否被迫 "unroll" 手动编写代码?
(编译器特定的解决方案将是最后的手段。)
您使用运行时大小 std::vector
不必要地向编译器隐藏了大小信息。像
template <std::size_t len>
class Buffer {
public:
void operation1(int i) { return buf[i % buf.size()]; }
void operation2() { ... }
private:
std::array<int, len> buf;
};
应该向优化器提供优化所需的信息,就像在 "raw array in function" 情况下一样。