Make sure bulk reading works with prefetching#16640
Make sure bulk reading works with prefetching#16640ktf wants to merge 8 commits intoroot-project:masterfrom
Conversation
|
@pcanal, this makes things work for me, albeit I am not sure it's the correct thing to do. I think the real issue is https://github.com/root-project/root/blob/master/tree/tree/src/TBranch.cxx#L1413 but I couldn't quite understand why / how to fix it. |
|
@ktf (I can reproduce the problem now). Commit b2c6904 seems to have broken the expectation of only one basket in flight, I also wonder how it interact with the interface, in particular, it is clear that this PR removes the crashs but does it lead to correct data being read through the bulk interface? |
Test Results 17 files 17 suites 3d 10h 37m 15s ⏱️ For more details on these failures, see this check. Results for commit 75a6cbf. ♻️ This comment has been updated with latest results. |
4d7941f to
e8bf8d3
Compare
|
Some tests are failing with |
|
@pcanal Indeed, this still breaks my (more elaborate) integration tests... |
|
Nevermind, I forgot to rebuild something and this does indeed break ABI compatibility because of the newly introduced vector.. |
|
@ktf Can you test the additional commit that I pushed here? This is another API breaking change (new function). |
|
Thanks. I am doing so right now. I should have something in an hour or so. |
Yep, I can reproduce it .... investigating. |
|
I pushed a fix to the memory leak. |
|
Unfortunately the Windows is related. I am checking. |
|
On the other hand, it seems to have fixed the leak and memory usage is back to expected. |
This is currently not the case when the branch has more than 1 basket.
To be used instead of TBuffer::SetBuffer when the incoming buffer is actually coming from a TBuffer[File]. This will reduce memory churn.
|
Actually, this is fix but might still not be doing what is meant :( .... and I am not sure if you actually need to use this features. What do you intend on gain by calling The feature enabled by (At least) there is optimization in place that actually counter to this and need to be removed (the optimization avoids a memory copy by sending the uncompressed buffer back to the user as is ... but then it is no longer there. And in essence the fix we have here is also incorrect :(. When the 'ClusterPrefetching' is on, we actually should always leave the basket as is in the list of basket for the next call to possibly use (at least until the end of the cluster). So you could indeed proceed with using this as it function (return the right result) but does not yet implement the |
|
I was enabling SetClusterPrefetch as part of the attempt to reduce read_calls when processing our AODs. Indeed I now notice that it's enough to simply do: // Was affected by https://github.com/root-project/root/issues/8962
// Re-enabling this seems to cut the number of IOPS in half
tree->SetCacheSize(25000000);
//tree->SetClusterPrefetch(true);
for (auto& reader : mBranchReaders) {
tree->AddBranchToCache(reader->branch());
}
tree->StopCacheLearningPhase();to obtain the same result, so I am fine to simply disable it for now. Do I understand correctly that I still need this patch, though, in case there is more than one basket? |
Apriori it does not intend have an effect on that.
What is the change (increase of the cache size or explicit cache learning or both)? |
Doing the caching at all. I thought prefetching was part of it, but apparently it is not. |
The names are really confusing ... sorry.
This later setting might be of interest in your case. |
|
Ok, thank you for your explanations. I can confirm that 1 works already for me. I will try 3. 2 I probably do not need, actually. |
Instead of relying on TBranch::fBasketSize use the actual compressed/ondisk size of the buffer to decide on the size allocated for the TBufferFile of the baskets. In particular in the example testBulkApi, there is a file where there is only one float branch with an initial basketsize of 320k. There is enough data stored to reach just passed 32MB (data happens to not be compressed) and thus OptimizeBaskets is called and settle on a basket size of 25MB. So the file is composed of 93 baskets of 320k for the first clusters and a single basket for the second cluster. In the previous code (before this commit), any basket created allocates a TBufferFile of size 'branch->GetBasketSize()'. So in the example above for the first few baskets, we allocated 25MB instead of the required 320k. This becomes a real issue if we also turn on `SetClusterPrefetch` which will load in memory all the baskets of a cluster and thus for our exmaple will allocate 25MB * 93, i.e. more than 2GB! (instead of the 29MB needed).
This is to now actually implement the purpose of `ClusterPrefetch` which is to keep the basket in memory to support random access within a cluster.

This is currently not the case when the branch has more than 1 basket.
This PR fixes #8962.