Why Visual Studio Isn’t 64-bit


#1

On Reddit I’ve seen a link to this, “Why Visual Studio Isn’t 64-bit”:

Are such 32-bit considerations taken sufficiently seriously in the future design of Rust?


#2

I think VS overstates its case. Telling people that want to use memory “put it in a 64-bit package that’s out of process” really isn’t a great story. And the devenv.exe I currently have open is sitting at 1,460,320 KB of Working Set, so I’m not sure how successful it is at “don’t use much memory”–especially when it needs a bunch of free in-proc address space for the GC to perform well.

Rust isn’t in the “let’s box everything on the heap by default” model, so it has far fewer pointers to begin with, which I think is the better way to keep things small.


#3

One of the attractive things about the rust ecosystem is how easy it makes cross compiling. Well, written portable code should be easy to target either 32 bit or 64 bit. This lets you be very flexible about which target you release if you find yourself in the situation they are in.

If you want to play with performance characteristics under the different builds its as easy as adding a new target in rustup and setting it on your build. I’ll give quick instructions for 64 bit Ubuntu.

First install the 32 bit target:

rustup target add i686-unknown-linux-gnu

You might also need 32bit libc. If so install them with:
sudo apt-get install libc6-dev-i386

Now write some benchmarks for the crate you are concerned about and run them with both targets. I’ll use my murmur3 crate:

stusmall@T440:~/Workspace/Upstream/murmur3$ cargo bench
    Finished release [optimized] target(s) in 0.0 secs
     Running target/release/deps/bench-f3c9e6ffd4bc0e07

running 3 tests
test bench_32      ... bench:          86 ns/iter (+/- 8) = 651 MB/s
test bench_x64_128 ... bench:          41 ns/iter (+/- 8) = 1365 MB/s
test bench_x86_128 ... bench:          49 ns/iter (+/- 9) = 1142 MB/s

test result: ok. 0 passed; 0 failed; 0 ignored; 3 measured

     Running target/release/deps/murmur3-bf9cdd4170472340

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

stusmall@T440:~/Workspace/Upstream/murmur3$ cargo bench --target=i686-unknown-linux-gnu
    Finished release [optimized] target(s) in 0.0 secs
     Running target/i686-unknown-linux-gnu/release/deps/bench-f3c9e6ffd4bc0e07

running 3 tests
test bench_32      ... bench:         113 ns/iter (+/- 11) = 495 MB/s
test bench_x64_128 ... bench:          88 ns/iter (+/- 9) = 636 MB/s
test bench_x86_128 ... bench:          61 ns/iter (+/- 10) = 918 MB/s

test result: ok. 0 passed; 0 failed; 0 ignored; 3 measured

     Running target/i686-unknown-linux-gnu/release/deps/murmur3-bf9cdd4170472340

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

#4

Besides pointers, usize is widely used and platform dependent. Using it to store the size of a container often feels wrong; nearly all containers do not need more than 32-bit length (16-bit is often enough), and if 64-bits really is required, the code won’t work on 32-bit platforms. But, it is convenient, usually works fine and saves conversions.

(IMO templating containers like vec over the index/length type would make sense, but of course be more tedious to use for little real gain.)


#5

Most likely, the actual reason is the same as in every other 32-bit software project of the 21st century.

assert(sizeof(int) == sizeof(void*));