【发布时间】:2020-07-03 05:12:42
【问题描述】:
另外,如果 Rust 编译器是从头开始编写(如 Go)而不是使用 LLVM,您估计 Rust 编译可能会快多少?
【问题讨论】:
标签: performance rust compilation
另外,如果 Rust 编译器是从头开始编写(如 Go)而不是使用 LLVM,您估计 Rust 编译可能会快多少?
【问题讨论】:
标签: performance rust compilation
Rust 编译中最耗时的部分通常是优化过程和最终代码生成,尽管可能存在其他部分存在问题的退化情况,例如使用 -Z time-passes 构建 rust-csv 会为最终的 csv crate 生成这个:
time: 0.000; rss: 174MB monomorphization_collector_root_collections
time: 0.002; rss: 53MB parse_crate
time: 0.000; rss: 53MB attributes_injection
time: 0.000; rss: 53MB recursion_limit
time: 0.000; rss: 53MB plugin_loading
time: 0.000; rss: 53MB plugin_registration
time: 0.000; rss: 53MB pre_AST_expansion_lint_checks
time: 0.000; rss: 56MB crate_injection
time: 0.000; rss: 57MB pre_AST_expansion_lint_checks
time: 0.000; rss: 57MB pre_AST_expansion_lint_checks
time: 0.000; rss: 58MB pre_AST_expansion_lint_checks
time: 0.000; rss: 58MB pre_AST_expansion_lint_checks
time: 0.072; rss: 178MB monomorphization_collector_graph_walk
time: 0.000; rss: 60MB pre_AST_expansion_lint_checks
time: 0.009; rss: 178MB partition_and_assert_distinct_symbols
time: 0.000; rss: 178MB find_cgu_reuse
time: 0.000; rss: 60MB pre_AST_expansion_lint_checks
time: 0.001; rss: 60MB pre_AST_expansion_lint_checks
time: 0.000; rss: 61MB pre_AST_expansion_lint_checks
time: 0.000; rss: 61MB pre_AST_expansion_lint_checks
time: 0.014; rss: 184MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.1)
time: 0.010; rss: 187MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.2)
time: 0.096; rss: 90MB expand_crate
time: 0.000; rss: 90MB check_unused_macros
time: 0.096; rss: 90MB macro_expand_crate
time: 0.000; rss: 90MB maybe_building_test_harness
time: 0.001; rss: 90MB AST_validation
time: 0.000; rss: 90MB maybe_create_a_macro_crate
time: 0.015; rss: 190MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.11)
time: 0.001; rss: 94MB complete_gated_feature_checking
time: 0.132; rss: 94MB configure_and_expand
time: 0.000; rss: 94MB prepare_outputs
time: 0.008; rss: 192MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.3)
time: 0.028; rss: 99MB hir_lowering
time: 0.003; rss: 99MB early_lint_checks
time: 0.001; rss: 101MB setup_global_ctxt
time: 0.000; rss: 101MB dep_graph_tcx_init
time: 0.001; rss: 101MB create_global_ctxt
time: 0.022; rss: 195MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.0)
time: 0.000; rss: 104MB looking_for_entry_point
time: 0.000; rss: 104MB looking_for_plugin_registrar
time: 0.000; rss: 104MB looking_for_derive_registrar
time: 0.031; rss: 107MB misc_checking_1
time: 0.023; rss: 113MB type_collecting
time: 0.001; rss: 113MB impl_wf_inference
time: 0.018; rss: 199MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.14)
time: 0.213; rss: 201MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.1)
time: 0.000; rss: 126MB unsafety_checking
time: 0.000; rss: 126MB orphan_checking
time: 0.052; rss: 126MB coherence_checking
time: 0.177; rss: 203MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.3)
time: 0.014; rss: 203MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.15)
time: 0.036; rss: 204MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.10)
time: 0.202; rss: 205MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.0)
time: 0.172; rss: 205MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.14)
time: 0.335; rss: 205MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.2)
time: 0.006; rss: 205MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.8)
time: 0.326; rss: 206MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.11)
time: 0.157; rss: 131MB wf_checking
time: 0.012; rss: 206MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.6)
time: 0.007; rss: 206MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.5)
time: 0.004; rss: 206MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.7)
time: 0.036; rss: 131MB item_types_checking
time: 0.463; rss: 206MB codegen_to_LLVM_IR
time: 0.000; rss: 206MB assert_dep_graph
time: 0.000; rss: 206MB serialize_dep_graph
time: 0.547; rss: 206MB codegen_crate
time: 0.010; rss: 166MB free_global_ctxt
time: 0.003; rss: 166MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.12)
time: 0.052; rss: 166MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.7)
time: 0.075; rss: 167MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.5)
time: 0.005; rss: 167MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.4)
time: 0.033; rss: 167MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.12)
time: 0.216; rss: 167MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.15)
time: 0.004; rss: 167MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.13)
time: 0.005; rss: 168MB LLVM_module_optimize_function_passes(bstr.9t899r4h-cgu.9)
time: 0.197; rss: 170MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.10)
time: 0.040; rss: 171MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.13)
time: 0.140; rss: 171MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.6)
time: 0.055; rss: 171MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.9)
time: 0.088; rss: 171MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.4)
time: 0.222; rss: 171MB LLVM_module_optimize_module_passes(bstr.9t899r4h-cgu.8)
time: 0.049; rss: 192MB LLVM_lto_optimize(bstr.9t899r4h-cgu.8)
time: 0.047; rss: 193MB LLVM_lto_optimize(bstr.9t899r4h-cgu.0)
time: 0.117; rss: 197MB LLVM_lto_optimize(bstr.9t899r4h-cgu.14)
time: 0.108; rss: 198MB LLVM_lto_optimize(bstr.9t899r4h-cgu.11)
time: 0.131; rss: 199MB LLVM_lto_optimize(bstr.9t899r4h-cgu.15)
time: 0.161; rss: 199MB LLVM_lto_optimize(bstr.9t899r4h-cgu.1)
time: 0.115; rss: 203MB LLVM_lto_optimize(bstr.9t899r4h-cgu.10)
time: 0.315; rss: 207MB LLVM_lto_optimize(bstr.9t899r4h-cgu.2)
time: 0.574; rss: 148MB item_bodies_checking
time: 0.844; rss: 148MB type_check_crate
time: 0.015; rss: 208MB LLVM_lto_optimize(bstr.9t899r4h-cgu.6)
time: 0.118; rss: 209MB LLVM_lto_optimize(bstr.9t899r4h-cgu.4)
time: 0.043; rss: 210MB LLVM_lto_optimize(bstr.9t899r4h-cgu.5)
time: 0.030; rss: 148MB match_checking
time: 0.014; rss: 210MB LLVM_lto_optimize(bstr.9t899r4h-cgu.12)
time: 0.019; rss: 150MB liveness_and_intrinsic_checking
time: 0.049; rss: 150MB misc_checking_2
time: 0.087; rss: 210MB LLVM_lto_optimize(bstr.9t899r4h-cgu.3)
time: 0.050; rss: 210MB LLVM_lto_optimize(bstr.9t899r4h-cgu.13)
time: 0.023; rss: 210MB LLVM_lto_optimize(bstr.9t899r4h-cgu.7)
time: 0.031; rss: 210MB LLVM_lto_optimize(bstr.9t899r4h-cgu.9)
time: 1.256; rss: 213MB LLVM_passes(crate)
time: 0.000; rss: 213MB join_worker_thread
time: 0.812; rss: 213MB finish_ongoing_codegen
time: 0.000; rss: 213MB serialize_work_products
time: 0.000; rss: 213MB link_binary_check_files_are_writeable
time: 0.003; rss: 213MB link_rlib
time: 0.000; rss: 213MB link_binary_remove_temps
time: 0.004; rss: 213MB link_binary
time: 0.004; rss: 213MB link_crate
time: 0.000; rss: 213MB llvm_dump_timing_file
time: 0.817; rss: 213MB link
time: 2.690; rss: 213MB total
正如您所见,具有大量时间计数的项目几乎都通过了 LLVM 优化,这就是 cargo check 如此有用的原因(它只是类型检查并停在那里,所以它通常比完整的代码生成快得多,甚至调试)。
AFAIK 这是高级优化的混合体,价格昂贵,而 rustc 历来会生成大型复杂的 IR,并给 llvm 留下一些混乱。而且 LLVM 本身很重,而且速度并不快。
我相信通过改进代码生成和添加或移动优化通道到 MIR 的组合,这种情况会慢慢得到改善。当然,我们还在不断努力从各个角度解决这个问题。
另外,如果 Rust 编译器是从头开始编写(如 Go)而不是使用 LLVM,您估计 Rust 编译可能会快多少?
如果您想要快速而低效,这几乎就是 using cranelift as the debug backend 的价值主张,所以您可以在那里获得数据。
但是在工时和实际 CPU 时间上进行优化的成本要高得多。
而且“debug rust”非常慢,以至于当有人问为什么他们的 rust 比他们的 python 慢时,这是人们首先检查的事情之一,95% 的时间是因为他们正在调试中编译。
正如 Calvin Weng 最近在 Pingcap 的系列文章所指出的,Rust 的模型和目的在很大程度上依赖于大量优化来实现其目标和承诺。
【讨论】: