Skip to content

Experiment with thread_local globals for I/O dispatch #11560

Closed
@alexcrichton

Description

@alexcrichton

Right now the main reason that all rust binaries are a minimum of 1MB is that all of the runtime's I/O is included in all binaries. The reason that all I/O is included is that LLVM can't eliminate the top-level I/O functions. The functions are included in a vtable which is then included in the local Task and it's pretty much impossible from there to be able to tell whether the vtable can be shrunk.

In theory we could do some optimizations at a frontend level to detect when I/O isn't used, but it'd also be nice if LLVM did this for us.

One idea I had tonight is that all I/O dispatch functions will not use a trait, but rather a set of thread_local globals (initialized when threads boot). From what I can tell, LLVM can eliminate a global if there are only writes to it (no reads), and in this world if you didn't use the networking I/O, you'd never read the networking I/O global, so all of that code could get eliminated.

Some points about this approach

  • I'm not sure it would work at all on platforms with no support for thread_local, currently android and windows (and osx 10.6)
  • This would slow down native task spawn times as they would always have to initialize these globals. I would naively assume that the slowdown is nothing compared to a syscall.
  • We'd need a nicer interface to thread_local because there would be dozens of these I/O functions
  • bare-bones usage of libnative (rust not bootstrapped from main) would not have these globals initialized. This I believe can be lumped into "you gotta call something::start first".

Despite these limitations, it's an incredibly frequent question raised on IRC about why rustc can't create a binary less than 1MB in size. This optimization would only apply to LTO'd programs, but it would at least work somewhere.

It's always been nagging at the back of my mind that we can't remove this I/O code, and this is the first idea I've had to get rid of this code, but I'm not sure how it will work out. I'm saddened that there would be more TLS globals, but the payoff may be worth it!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions