Kobzol/cargo-wizard

Why -Ctarget-cpu=native?

bbstilson opened this issue · 3 comments

This is not necessarily a bug per-se, but more of a question prompted by several days worth of debugging.

I am building a .so binary for python bindings via pyo3. I made a docker image to isolate the host machine from the target machine so that I could build binaries for different Ubuntu versions.

When setting up this project, I ran the wizard, and it added "-Ctarget-cpu=native" to the [build] section in the .cargo/config.toml. This was merged into source control.

To make a very long story short, the binary built in the docker container on CI (an AWS EC2 instance) was different than the binary built in the same docker container on my local machine. The root cause was the physical CPUs being different on AWS vs my local machine (skylake-avx512 vs skylake, respectively). This was leaking into the docker images, which resulted in different binaries depending on where the images were built.

My questions are:

  1. Is it wise to suggest the "-Ctarget-cpu=native", and, if so, what is the value? I read the documentation for this flag, but it's not particularly instructive on what the value of this flag is.

  2. Should I not be merging the .cargo/config.toml to source control? Or, if I should, should the target-cpu flag be applied via local envvars instead of being added to the global config?

Any advice or insight is greatly appreciated.

Hi, sorry for causing issues on your end :)

  1. That's a good question. Assuming that you want to get the best performance on your local machine, -Ctarget-cpu=native is usually what you want, since the compiler will then try to use the best instructions available for your hardware. It is also a good choice if you build the program that you execute directly on the machine where it is deployed.

    Where it is a bad choice is if you want to build the binary on machine A and then distribute it to machine B.

    I'm not sure how to resolve this in a general way. On one hand, I want the fast-runtime profile to really be "the best thing possible", so that you don't miss out on some useful options. On the other hand, for a distribution profile, this flag is really not a good idea. Maybe we could have two profiles (runtime-local and runtime-dist?), but that would make the tool a bit more complicated. Maybe cargo-wizard could ask if the binary is supposed to be used on the same machine or not.

    Or, at the very least I could include some warning in the documentation or in the output of cargo-wizard that warns that this flag is machine specific.

  2. That's also a very good question 😆 It usually annoys me when this file is committed into VCS, because I often want to use my local options there, and then it conflicts with the file from VCS. Probably a better idea here is to use config.toml that is stored e.g. in $HOME (https://doc.rust-lang.org/cargo/reference/config.html), so that it applies generally to all your Cargo projects, without having to deal with the committed file (the committed file will overwrite the global setting though).

    Committing -Ctarget-cpu=native into VCS is a bad idea, but on the other hand, it might make sense for some other flags that are e.g. required for the project to compile at all. So, as usually, the answer is it depends

Thank you for the detailed response. This is really helpful.

Your motivation for populating that rustc flag makes sense. I definitely got hit by a Skill Issue ™️ . A warning might be useful for future noobs such as myself 😅

You have convinced me to remove the .config from git and instead encourage devs to use $CARGO_HOME/config.toml.

Thanks again.

Added a warning in #18:
image