Can I use parfor within parfeval in MatlabR2019b and if yes, how?
Ältere Kommentare anzeigen
I'm encountering an issue with my MATLAB R2019b GUI project. I'm trying to display two sets of 4DCT (Four-Dimensional Computed Tomography) images simultaneously. Each set contains 10 CT volumes. While displaying the first case(two sets), I want to asynchronously load additional sets in the background. My approach involves using parfeval(@select_data, x, data{idx}) for each 4DCT, where select_data is a function utilizing parfor to read the 10 DICOM volumes.
When I run select_data independently, it performs well, utilizing all available workers efficiently (e.g., 12 workers). However, when I use parfeval, only one additional worker is utilized, leading to slower loading times (about 30-40 seconds per 4DCT). Also it causes lag in the main thread, even though I expect multiple workers to be employed for the loading process and the rest available for my main.
Here are the server specs I have access to:
CPU(s): 24
Thread(s) per core: 2
Core(s) per socket: 6
Socket(s): 2
Memory: 70GB
I've attempted to limit the number of workers to 8 in the parpool, leaving 4 cores free to handle the main GUI thread, but the lag persists.
It's possible that the issue lies with the usage of parfor within parfeval, which might not be leveraging all available workers as expected?
6 Kommentare
Damian Pietrus
am 27 Mär. 2024
You can't currently nest parallel functions like parfeval and parfor together. For example, when you have a parfor loop that calls another function that contains a parfor, the inner function runs in serial. This should explain why select_data runs well independently but not when called from parfeval.
Are you only calling parfeval twice (one for each set), or more than that? Am I correct in understanding that you're using parfeval so that you can display both images simultaneously, and that running select_data independently only produces one image?
max_hid
am 27 Mär. 2024
Bearbeitet: Edric Ellis
am 28 Mär. 2024
Edric Ellis
am 28 Mär. 2024
Damian is correct that by default it is not possible to get nested layers of parallelism. However, if you're willing to to perform some additional setup, and some additional code refactoring, it can be done. (One problem is that you're not allowed to place parfor directly in the body of another parfor - but you can perfectly well hide it inside a function). Here's an untested sketch of how you might make this work.
c = parcluster('Processes');
c.NumThreads = 4; % Required to allow us to create thread pools on the process workers
p = parpool(c, 4);
% Get each process worker to build its own thread pool
parfevalOnAll(p, @parpool, 0, 'Threads', 4);
parfor i = 1:N
out(i) = myfcn(i);
end
function out = myfcn(in)
out = 0;
% This will run in parallel using the thread pool assigned to this process
% worker
parfor i = 1:in
out = out + 1;
end
end
Edric Ellis
am 5 Apr. 2024
I'm still not 100% sure I understand where the problem is in your code. Here are some thoughts:
- Only use fetchOutputs if you need the output of a specific Future "right now". This will block for it to complete
- You might be able to use fetchNext if you want to retrieve outputs in the order that they complete. However, this will only change the ordering of when you get the results, it will not change how long it takes until the final result is available.
- There are various ways that you can trigger actions on completion of Futures. For instance, you could use afterAll to trigger an action when all elements of your futures array has finished. This approach leaves your client completely idle while the workers are busy.
Antworten (0)
Kategorien
Mehr zu Parallel for-Loops (parfor) finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!