c语言中visit的头文件,c – 优化std :: visit可能吗?

我刚看了一个更简单的

example.该表是在编译时生成的.时间可能花在std :: __ detail :: __ variant :: __ gen_vtable_impl< ...>中生成的lambdas中.出于某种原因,这些基本上呼叫访问者的lambda不会省略检查变体的实际类型.

此函数允许编译器为访问lambda的四个不同版本创建代码,内联到std :: visit内部创建的lambdas,并将指向这些lambda的指针存储在静态数组中:

double test(std::variant v1, std::variant v2) {

return std::visit([](auto a, auto b) -> double {

return a + b;

}, v1, v2);

}

这是在测试中创建的:

(...) ; load variant tags and check for bad variant

lea rax, [rcx+rax*2] ; compute index in array

mov rdx, rsi

mov rsi, rdi

lea rdi, [rsp+15]

; index into vtable with rax

call [QWORD PTR std::__detail::__variant::(... bla lambda bla ...)::S_vtable[0+rax*8]]

这是为< double,double>生成的.游客:

std::__detail::__variant::__gen_vtable_impl<:__detail::__variant::_multi_array double>, std::variant)::{lambda(auto:1, auto:2)#1}&&, std::variant&, test(std::variant, std::variant)::{lambda(auto:1, auto:2)#1}&&)>, std::tuple, std::variant)::{lambda(auto:1, auto:2)#1}&&, test(std::variant, std::variant)::{lambda(auto:1, auto:2)#1}&&>, std::integer_sequence >::__visit_invoke(test(std::variant, std::variant)::{lambda(auto:1, auto:2)#1}, test(std::variant, std::variant)::{lambda(auto:1, auto:2)#1}&&, test(std::variant, std::variant)::{lambda(auto:1, auto:2)#1}&&):

; whew, that is a long name :-)

; redundant checks are performed whether we are accessing variants of the correct type:

cmp BYTE PTR [rdx+8], 1

jne .L15

cmp BYTE PTR [rsi+8], 1

jne .L15

; the actual computation:

movsd xmm0, QWORD PTR [rsi]

addsd xmm0, QWORD PTR [rdx]

ret

如果探查器将这些类型检查的时间和内联访问者的时间归因于std :: __ detail :: __ variant :: __ gen_vtable_impl< ...>,而不是给你完整的800多个,我不会感到惊讶深度嵌套的lambda的字符名称.

我在这里看到的唯一通用优化潜力是省略lambda中不良变体的检查.由于lambda只通过函数指针调用,只有匹配的变量,编译器将很难静态发现检查是多余的.

decltype(auto) std::__1::__variant_detail::__visitation::__base::__dispatcher<1ul, 1ul>::__dispatch<:__1::__variant_detail::__visitation::__variant::__value_visitor double>, std::__1::variant)::$_0>&&, std::__1::__variant_detail::__base&, std::__1::__variant_detail::__base&>(std::__1::__variant_detail::__visitation::__variant::__value_visitor, std::__1::variant)::$_0>&&, std::__1::__variant_detail::__base&, std::__1::__variant_detail::__base&): # @"decltype(auto) std::__1::__variant_detail::__visitation::__base::__dispatcher<1ul, 1ul>::__dispatch<:__1::__variant_detail::__visitation::__variant::__value_visitor double>, std::__1::variant)::$_0>&&, std::__1::__variant_detail::__base&, std::__1::__variant_detail::__base&>(std::__1::__variant_detail::__visitation::__variant::__value_visitor, std::__1::variant)::$_0>&&, std::__1::__variant_detail::__base&, std::__1::__variant_detail::__base&)"

; no redundant check here

movsd xmm0, qword ptr [rsi] # xmm0 = mem[0],zero

addsd xmm0, qword ptr [rdx]

ret

也许您可以检查生产软件中实际生成的代码,以防它与我在示例中找到的代码不同.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值