Project-OSRM / osrm-backend

Open Source Routing Machine - C++ backend
http://map.project-osrm.org
BSD 2-Clause "Simplified" License
6.45k stars 3.42k forks source link

Asynchronously write out auxiliary data structures #3621

Open daniel-j-h opened 7 years ago

daniel-j-h commented 7 years ago

Currently looking over the extractor and seeing serial I/O there. There is often no need for us waiting for I/O to happen.

For the compressed node based graph dumping I'm doing the following

std::future<void> writing;

BOOST_SCOPE_EXIT_ALL(&) { if (writing.valid()) writing.wait(); };

if (config.dump) {
  writing = std::async(std::launch::async, [&] { write(file, all_the_things); });
}

with the void specialization for future acting as a synchronization point on which we can block when we need to. I think we could do the same in various places there, carefully transferring the future's ownership and only blocking at the end or where it matters.

daniel-j-h commented 7 years ago

Here's an idea: we could abstract asynchronous I/O behind the current abstractions. In the design proposal you would have e.g. a AsyncOutStream. At the moment with our FileReader and FileWriter we could add member functions for now.

The FileWriter could store a vector of std::future<void> IO actions (make them strictly typed IOActions), to which you could add your async operation by means of calling a member function.

The FileWriter's destructor could then block until all IO actions are done. In addition the FileWriter could allow you to transfer the ownership of the IO action out of the FileWriter where the user could explicitly block when needed.

The same works for the FileReader where IO actions could fill elements or return by-value futures (move semantics should make this possible). I see the main benefit primarily in the FileWriter for now, though.