【发布时间】:2011-12-01 06:21:54
【问题描述】:
我有以下情况:有大量模板,例如 std::vector,它们会调用 memmove() 来移动数组的一部分。有时他们会想要“移动”长度为零的部分——例如,如果数组尾部被移除(如std::vector::erase()),他们会想要移动数组的其余部分,这会发生长度为零,并且在编译时将知道该零(我看到了反汇编 - 编译器知道)但编译器仍会发出 memmove() 调用。
所以基本上我可以有一个包装器:
inline void callMemmove( void* dest, const void* source, size_t count )
{
if( count > 0 ) {
memmove( dest, source, count );
}
}
但是如果count 在我不想要的编译时未知,这会引入额外的运行时检查。
是否有可能使用__assume hint 向编译器指示如果它确定count 为零,它应该消除memmove()?
【问题讨论】:
-
你希望用这个保存什么?似乎是微微优化?您要保存两个分支(查看
memmove的基本 gnu 实现)? -
@Nim:分支,对
memmove()的调用以及(最重要的部分)允许优化memmove()调用周围的一些代码 - 没有调用意味着它的参数准备是并不需要。是的,它是微秒,但它可以节省微秒。 -
哦,来吧,伙计们,尖牙似乎有足够的经验知道“过早的优化是万恶之源”,除非你有严重的理由,否则你不应该实现自己的向量。在某些情况下,两者都有原因,现在让我们假设这是其中之一,让我们尝试解决问题,而不是宣布它没有问题。
-
奇怪的是,当编译器已经检测到长度为 0 时,它应该发出对
memmove的调用。实际上,调用应该是内联的,零大小的循环会被检测到并被忽略。为什么没有发生这种情况?您是否链接到动态运行时?如果是这样,请为memmove编写一个包装器,看起来就像你在上面写的那样。 -
@Konrad Rudolph:AFAIK 原因是
memmove()是在 Visual C++ 运行时源中的汇编中实现的,而不是提供给编译器的。
标签: c++ visual-c++ optimization compiler-optimization