4

I'm syncing my node on 32 CPUs, and it's super slow.

Obviously, syncing doesn't go in parallel. I wonder if there is any fundamental obstacle for "divide and conquer" way of doing it.

So let's say we have 62 blocks, and 2 CPUs. We divide it by half, and the first CPY syncs 1-32 blocks, and 2nd cpu syncs 33-64 blocks, after both tasks are completed, we are checking that 32 and 33 blocks match.

Am I missing something? This feature seems so simple to me but somehow not implemented.

8

What makes you think that this isn't implemented?

Block download is already multithreaded and blocks are downloaded out of order. Everything that can be verified in a block without requiring other blocks (such as the PoW matching the PoW stated in the block header, merkle root, etc.) are verified when the block is received. This all happens in separate threads.

But the bulk of verification is checking that the transactions within the blocks are valid. This cannot be done without having verified all of the blocks previous to the one being verified, so this is unfortunately a serial operation that cannot be parallelized.

The crux of the issue has to do with the UTXO set. Suppose block 2 has a transaction that spends an output created in a transaction that is in block 1. If you receive block 2 and start verifying transactions before you have block 1, then you will be unable to verify the transaction whose parent(s) are in block 1. Thus you must wait for block 1 to be received and verified before you can verify block 2.

Of course you can still check the other things in block 2 and write it to disk first, then proceed to download more blocks. These just need to be queued for the actual transaction verification.

The transaction verification involves adding and removing items from the UTXO database. This database needs to be written to disk which means that there will be a lot of disk I/O which is generally slow. The database is cached in memory but is flushed to disk when the in memory cache becomes full. You can make this faster by increasing this cache. In your bitcoin.conf, add a line dbcache=<n> where <n> is the amount of RAM in MiB that you want to dedicate to the cache.

The default dbcache is 450 MiB, so setting a dbcache value larger than 450 will speed up syncing as more of the database is cached and thus less disk I/O is needed. A dbcache of 8000 is large enough that the entire database will fit in memory and thus only be written to disk once. If you have enough RAM for this, then setting dbcache=8000 will allow for the fastest sync time.

  • Thanks Andrew for such a good answer. Now it's clear why it's implemented in the current way. Increasing cache didn't improve the speed too much(visually), also it makes abrupt shutdowns of the machine more critical, as the cache hasn't been saved on the disk, and the bitcoind will have to do "Rolling forward" for all already downloaded and verified blocks. – Artem Ibragimov Aug 19 at 8:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.