Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parallel preprocessing of blocks + transactions #1360

Merged
merged 18 commits into from
Dec 14, 2018
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Parallelize loading/saving object_database
  • Loading branch information
pmconrad committed Dec 7, 2018
commit e5ba271c264c2c4173e12f37db9d0def1e068ab8
17 changes: 15 additions & 2 deletions libraries/db/object_database.cpp
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@

#include <fc/io/raw.hpp>
#include <fc/container/flat.hpp>
#include <fc/thread/parallel.hpp>
#include <fc/uint128.hpp>

namespace graphene { namespace db {
@@ -72,14 +73,20 @@ void object_database::flush()
{
// ilog("Save object_database in ${d}", ("d", _data_dir));
fc::create_directories( _data_dir / "object_database.tmp" / "lock" );
std::vector<fc::future<void>> tasks;
tasks.reserve(200);
for( uint32_t space = 0; space < _index.size(); ++space )
{
fc::create_directories( _data_dir / "object_database.tmp" / fc::to_string(space) );
const auto types = _index[space].size();
for( uint32_t type = 0; type < types; ++type )
if( _index[space][type] )
_index[space][type]->save( _data_dir / "object_database.tmp" / fc::to_string(space)/fc::to_string(type) );
tasks.push_back( fc::do_parallel( [this,space,type] () {
_index[space][type]->save( _data_dir / "object_database.tmp" / fc::to_string(space)/fc::to_string(type) );
} ) );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Does this really increase performance? Isn't IO the bottleneck here?
  2. Perhaps better if we adopt the behavior of ChainBase, store not only data but also indexes, to improve startup speed (may slow down shutdown speed though). This belongs to another ticket.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IO isn't necessarily the bottleneck, e. g. when restarting a node the previously saved data might still be in system buffers.

Copy link
Member

@abitmore abitmore Nov 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is save aka writing but not reading. When we're writing, usually the data has changed, even if it didn't change much, since we're writing to temporary (aka different) files, so the buffer doesn't help.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course disk buffer helps when writing.
On a system with a slow disk and the bare minimum of RAM you're right, parallelizing won't help - but it won't hurt either.
With sufficient buffer memory, or on a RAM-disk, parallel saving should be faster.

}
for( auto& task : tasks )
task.wait();
fc::remove_all( _data_dir / "object_database.tmp" / "lock" );
if( fc::exists( _data_dir / "object_database" ) )
fc::rename( _data_dir / "object_database", _data_dir / "object_database.old" );
@@ -103,11 +110,17 @@ void object_database::open(const fc::path& data_dir)
wlog("Ignoring locked object_database");
return;
}
std::vector<fc::future<void>> tasks;
tasks.reserve(200);
ilog("Opening object database from ${d} ...", ("d", data_dir));
for( uint32_t space = 0; space < _index.size(); ++space )
for( uint32_t type = 0; type < _index[space].size(); ++type )
if( _index[space][type] )
_index[space][type]->open( _data_dir / "object_database" / fc::to_string(space)/fc::to_string(type) );
tasks.push_back( fc::do_parallel( [this,space,type] () {
_index[space][type]->open( _data_dir / "object_database" / fc::to_string(space)/fc::to_string(type) );
} ) );
for( auto& task : tasks )
task.wait();
ilog( "Done opening object database." );

} FC_CAPTURE_AND_RETHROW( (data_dir) ) }