C++ 中文周刊 2024-08-18 第166期

2024-08-19 15:18:56 浏览数 (1)

文章

彻底理解 C ABI

https://zhuanlan.zhihu.com/p/692886292

今天群聊提到了一个场景,unique_ptr传值加move 并不能完美优化掉,看代码

代码语言:javascript复制

代码语言:javascript复制
void consume(int* ptr);

void foo(int* ptr) {
  consume(ptr);
}


foo:
        jmp     consume@PLT


void consume(unique_ptr<int> ptr);

void foo(unique_ptr<int> ptr) {
  consume(std::move(ptr));
}


foo(std::unique_ptr<int, std::default_delete<int> >):
        push    rbx
        sub     rsp, 16
        mov     rax, QWORD PTR [rdi]
        mov     QWORD PTR [rdi], 0
        lea     rdi, [rsp 8]
        mov     QWORD PTR [rsp 8], rax
        call    consume(std::unique_ptr<int, std::default_delete<int> >)
        mov     rdi, QWORD PTR [rsp 8]
        test    rdi, rdi
        je      .L1
        mov     esi, 4
        call    operator delete(void*, unsigned long)
.L1:
        add     rsp, 16
        pop     rbx
        ret
        mov     rbx, rax
        jmp     .L3
foo(std::unique_ptr<int, std::default_delete<int> >) [clone .cold]:
代码语言:javascript复制

主要原因是 函数实参在 caller 方析构, unique_ptr没有彻底优化掉。感觉可以优化掉

改成传引用,传&&甚至改成not_null都能省掉

代码语言:javascript复制
void consume(not_null<int> ptr); //std::unique_ptr<int> && 也可以

void foo(not_null<int> ptr) {
    consume(ptr);  //
}
/*
foo(not_null<int>):
        jmp     consume(not_null<int>)
*/
代码语言:javascript复制

感谢anms nugine ni fvs zwuis 讨论

godbolt https://godbolt.org/z/fbqEa4M1r

noexcept Can (Sometimes) Help (or Hurt) Performance

https://16bpp.net/blog/post/noexcept-can-sometimes-help-or-hurt-performance/

使用noexcept需要保证没有异常,否则生成的代码代价更高

通常来说noexcept是给move用的

另外有一个搞笑的场景

noexcept affects libstdc ’s unordered_set

https://quuxplusone.github.io/blog/2024/08/16/libstdcxx-noexcept-hash/

libstdc 的 unordered set 对于noexcept限定 针对hash函数有特化 如果hash函数是noexcept 认为函数计算很轻,不额外保存key hash,否则会缓存key hash加速

这就导致一个尴尬的场景,对于int,这种优化是对的,对于string hash接口使用noexcept会弄巧成拙速度更慢

标准库对于noexcept限定应该给用户端保留余地,不要影响效果,如果影响,最好给出api约定,比如transparent compare

这种莫名其妙的限制很坑,可能喜欢秀一下用noexcept正好掉坑里

libstdc 说明 在这里 https://gcc.gnu.org/onlinedocs/libstdc /manual/unordered_associative.html

Temporarily dropping a lock: The anti-lock pattern

https://devblogs.microsoft.com/oldnewthing/20240814-00/?p=110129

异步lock暂时解锁的组件。代码

代码语言:javascript复制
代码语言:javascript复制
template<typename Mutex>
struct anti_lock
{
    anti_lock() = default;

    explicit anti_lock(Mutex& mutex)
    : m_mutex(std::addressof(mutex)) {
        if (m_mutex) m_mutex->unlock();
    }

private:
    struct anti_lock_deleter {
        void operator()(Mutex* mutex) { mutex->lock(); }
    };

    std::unique_ptr<Mutex, anti_lock_deleter> m_mutex;
};

winrt::fire_and_forget DoSomething()
{
    auto guard = std::lock_guard(m_mutex);

    step1();

    // All co_awaits must be under an anti-lock.
    int cost = [&] {
        auto anti_guard = anti_lock(m_mutex);
        return co_await GetCostAsync();
    }();

    step2(cost);
}
代码语言:javascript复制

Surprisingly Slow NaNs

https://voithos.io/articles/surprisingly-slow-nans/

代码存在0除0导致NAN NAN导致性能下降

规避?isnan判定 DCHECK

What's so hard about class types as non-type template parameters?

https://brevzin.github.io/c /2024/08/15/cnttp/

NTTP 支持类实例的困难原因 无法判定相等

有operator template()提案和反射提案的加持下可能有解

Reflection-based JSON in C at Gigabytes per Second

https://lemire.me/blog/2024/08/13/reflection-based-json-in-c-at-gigabytes-per-second/

反射给普通库带来压倒性序列化速度, 10倍以上

反射快来吧

互动环节

上周熬夜看了街霸6比赛 直接给我看的不困了,尤其是肯打aki那场,看的我心率110,真刺激

不过熬夜的后果就是一周都缓不过来。睡眠问题非常大,累计起来了,石油杯这个比赛作息太抽象了

时间真快啊,转眼夏天就过去了我靠,感觉啥也没干

东西太多根本看不过来,时间真是不够用

0 人点赞