是否可以确保复制省略?

发布于 2024-11-10 01:34:46 字数 455 浏览 0 评论 0原文

复制省略是一种简洁的优化技术,在某些情况下依赖于复制省略实际上比“手动”传递引用更快

因此,假设您已经确定了一条关键代码路径,您依赖于编译器为代码路径执行复制省略以获得最大性能的事实。

但现在您依赖于编译器优化。

是否有任何(显然是特定于编译器的)方法来确保实际执行复制省略,并让编译器(或其他工具)在无法执行复制省略时生成警告/错误?

(我正在考虑与 Visual C++ 的 __forceinline 非常相似的东西,如果编译器未内联标记的函数,则会生成警告。)

Copy elision is a neat optimization technique and in some cases relying on copy elision can actually be faster than passing around references "by hand".

So, let's assume you have identified a critical code path where you rely on the fact that the copy elision is performed by your compiler for the code path for maximum performance.

But now you are relying on a compiler optimization.

Is there any (compiler specific, obviously) way to ensure that the copy elision is actually performed and have the compiler (or another tool) generate a warning/error if the copy elision cannot be performed?

(I'm thinking of something remotely similar to Visual C++'s __forceinline than will generate a warning if the function marked thus isn't inlined by the compiler.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

愛上了 2024-11-17 01:34:47

不。

但是您可以编写一个等效的代码,尽管完全不可读,代码:

BigObj f()
{
    BigObj x(g());
    x.someMethod();
    return x;
}

//...
BigObj z = f();
//...

被翻译(带有复制省略)为:

void f(BigObj* obj)
{
    new(obj) BigObj(g());
    obj->someMethod();
}

//...
char z[sizeof(BigObj)];
f((BigObj*)&z[0]);
//...
((BigObj*)&z[0])->~BigObj();

但说真的,只需以编译器可以省略副本的方式编写代码即可。即仅返回一个对象而不分支:

BigObj f()
{
    BigObj x, y;
    // use x and y
    if(condition)
        return x;
    else
        return y;
    // cannot be elided
}


BigObj f()
{
    if(condition)
    {
        BigObj x;
        return x;
    }
    else
    {
        BigObj y;
        return y;
    }
    // can be elided
}

No.

But you can write an equivalent, although completely unreadable, code:

BigObj f()
{
    BigObj x(g());
    x.someMethod();
    return x;
}

//...
BigObj z = f();
//...

is translated (with copy elision) to:

void f(BigObj* obj)
{
    new(obj) BigObj(g());
    obj->someMethod();
}

//...
char z[sizeof(BigObj)];
f((BigObj*)&z[0]);
//...
((BigObj*)&z[0])->~BigObj();

But seriously, just write your code in such a way that the compiler can elide the copy. I.e. return only one object without branching:

BigObj f()
{
    BigObj x, y;
    // use x and y
    if(condition)
        return x;
    else
        return y;
    // cannot be elided
}


BigObj f()
{
    if(condition)
    {
        BigObj x;
        return x;
    }
    else
    {
        BigObj y;
        return y;
    }
    // can be elided
}
柒七 2024-11-17 01:34:47

不是真的,除了在复制构造函数中放置一个 assert(false);

否则,使用您最喜欢的分析器来衡量应用程序中有趣的部分是否足够快。

Not really, except putting an assert(false); in the copy constructor.

Otherwise use your favorite profiler to measure that the interesting parts of your app is fast enough.

枫林﹌晚霞¤ 2024-11-17 01:34:47

在 C++1z 中(预计 2017 年),某些情况下需要保证复制省略:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0135r0.html

根据 公共 cppreference.com 编译器功能支持 wiki GCC 7+ 和 Clang 4+ 确保了这一点。

幸运的是,优化方面不需要启用较新的语言支持,因为它是纯粹的优化(遵循较旧的语言标准津贴)。

此外,在优化应用时允许复制构造函数不可用可能需要在编译期间启用较新的语言标准,或者使用不需要严格一致性的松散或扩展模式(例如,可能是 GCC 的 -fpermissive< /代码>)。

In C++1z (expected 2017), some cases will be required to guarantee copy elision:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0135r0.html

Per the communal cppreference.com compiler feature support wiki GCC 7+ and Clang 4+ ensure this.

The optimization side of this fortunately should not require enabling newer language support, since it's a pure optimization (following older language standard allowances).

Also allowing the copy constructor to be unavailable when the optimization applies probably will require the newer language standard to be enabled during compilation, or use of a loose or extended mode that doesn't demand strict conformance (e.g. potentially GCC's -fpermissive).

靑春怀旧 2024-11-17 01:34:47

是否有任何(显然是特定于编译器的)方法来确保
复制省略实际上被执行并且让编译器(或另一个
工具)如果无法进行复制省略,则会生成警告/错误
执行了吗?

gcc (trunk) (尚未发布 v14)具有 -Wnrvo

“如果编译器未在 [ 允许的上下文中消除从局部变量到函数返回值的复制,则发出警告class.copy.elision]。这种省略通常称为命名返回值优化。”

gcc (trunk) 可在 https://godbolt.org/

Is there any (compiler specific, obviously) way to ensure that the
copy elision is actually performed and have the compiler (or another
tool) generate a warning/error if the copy elision cannot be
performed?

gcc (trunk) (not yet released v14) has -Wnrvo

"Warn if the compiler does not elide the copy from a local variable to the return value of a function in a context where it is allowed by [class.copy.elision]. This elision is commonly known as the Named Return Value Optimization."

gcc (trunk) is available on https://godbolt.org/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文