Call parfeval using global variables?
显示 更早的评论
I am using parfeval() to do multithread logic. I have 16 cores. The documention mentions listing the calling parameters as arguments in parfeval, for example:
for ii = 1:partition
f(ii) = parfeval(@func, 1, a, b, c);
end
My three a b c arguments happen to be globals. Can I call parfeval this way instead, and pick up the globals in func? The return value is also a global.
for ii = 1:partition
f(ii) = parfeval(@func,0);
end
I suspect not, since my code isn't working.
Also, one of the three arguments is a pathname to a DOS batch file, which I execute with a System call. Is this possible across multiple cores?
采纳的回答
更多回答(1 个)
Walter Roberson
2023-1-23
When you pass a global as a parameter, what is received in the called routine is treated as a local. For example, assigning to that parameter does not change the global variable.
This is the case when using parfeval as well. The global a, b, c in your call would be received as local.
To emphasize: if you had
function result = func(a, b, c)
result = some_internal_function;
end
function result = some_internal_function
global a b c
result = a*25 + b*5 + c;
end
then the fact that you passed global variable a into func does not mean that a gets treated as global inside some_internal_function. You would have to code something like
function result = func(a_in, b_in, c_in)
global a b c
a = a_in; b = b_in; c = c_in;
result = some_internal_function;
end
and then a b c would become global within that worker for as long as the worker continues to live. But if some_internal_function modified (say) b then the change would not affect any other worker and would not affect the client.
10 个评论
Kurt
2023-1-24
Process-based parfor is able to system()
There is no possibility in current versions that a global variable will be copied in to a process-based worker . Looks like the same is true for background pools
pool = backgroundPool()
global X
X = 2;
for K = 1 : 3
F(K) = parfeval(pool, @mycode, 1, X);
end
wait(F);
G = fetchOutputs(F, 'uniform', false)
X
function result = mycode(inval)
global X
if isempty(X)
result = NaN;
X = -3;
else
X = X + X;
result = inval + X;
end
inval = 7; %does modifying this change the global ?
end
In the above, the reason that the third output is numeric is that there are two workers in the pool, so each of them gets an independent global workspace . Each of those starts with an empty global workspace, so isempty(X) finds empty. But there are three tasks, so the third task gets the existing global workspace of whichever of the two workers it ends up executing in, and the previous task modified its global workspace.
So when a worker pool is created, each worker gets a global workspace that is empty. If something happens to modify the global workspace by way of code executing on the worker then that worker's global workspace will be updated (without affecting anything else.) As long as the worker exists, changes on the worker to its global workspace will persist.
But you can see that even though we passed the global in as parameter, modifying it (inval = 7) did not have any global effect, and changes to the globals that live on the workers did not have any effect on the client.
Walter Roberson
2023-1-24
You mention DOS. I wonder if System.Diagnostics.Process is supported on background pool workers?
I seldom boot Windows these days, so this is not something I can easily test.
Walter Roberson
2023-1-25
However these are not designed to connect to "cores", only to IP addresses.
Walter Roberson
2023-1-25
You can use addAttachedFiles on a parallel pool -- and my tests show you can do it on a backgroundPool as well. It does not matter whether you then use parfor with the pool or if you use parfeval with the pool: the files will already exist in the workers either way.
Walter Roberson
2023-2-1
What difficulty did you encounter with addAttachedFiles
类别
在 帮助中心 和 File Exchange 中查找有关 Parallel Computing Fundamentals 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!