即使对于内部非常“浅”的计算
simple()
Julia文档建议使用
remotecall_fetch()
而不是
fetch( remotecall( ... ) )
:
函数
为此目的而存在。相当于
fetch(remotecall(...))
但效率更高。
这个
[PARALLEL]
-过程
@spawn
fetch()
日常开支
这是一个经常被忽视的话题,很高兴能积极认识到这一主题并尝试对其进行推理。事实上,这是造成不良影响的常见根源
[平行]
-进程调度最终性能。
If indeed interested in details
, getting both the mathematical model + an interactive UI-tool to simulate / evaluate the net-effects of the
overhead-strict speedup
formula on
[PARALLEL]
code-executions for as much as 2 .. 8000+ CPU-cores, feel free to read more on this
here
这里的主要“可疑”是进程间依赖性的价值:
-
其中一个可能隐藏在系统功能内部
rand()
. 在使用加密功能强大的实现的情况下,每次调用
兰德()
必须
更新随机性的中心源状态。这意味着,由于这个特殊的原因,所有、实际上所有衍生的进程都必须建立并维护一个到这个中央共享服务的队列,这个队列在简单的
[SEQ]
[PAR]
-
另一个是{prior |next}-循环步骤依赖,在对
简单()
-流程实例。如下图所示,这种相互依存实际上使得所有可能产生的调用都必须安排为纯调用
[顺序]
-流程计划和“剩余”
sum()
[平行]
-过程时间表。
实际的相互进程间依赖性
以便
-处理效率更高:
// +-------------<---- a way to "inject" a for-loop
// | +----------<---- NOT CONSUMED AT ALL
// | |
// | | +--******* BUT ********* DEPENDENCY
// | | |
// | | v
// | | +-------<-->- v[]-{prior|next}-step DEPENDENCY
// | | | +-<-->- c[]-{prior|next}-step DEPENDENCY
// | | | |
// function simple( i, Q, vt_0, ct_0 )
@everywhere function simple( N, Q, vt_0, ct_0, aVEC )
for i = 1:N
aVEC[i] = sum( ( rand(1:i), vt_0, ct_0 ) )*2
// a = sum( ( rand(1:i), vt_0, ct_0 ) )*2
// ret a
end
同时通过以下方式添加具有显式进程间通信的CSP通道:
{ put!() | take!() }
信道方法可能会解决正在通信的这种依赖性,猜猜看,协同路由调度只会增加额外的开销,所以期望付出更多才能得到更少。
关于原始分析的一个小说明:
在所有情况下,建议放置一个
tic() .. toc()
-括号紧靠测试的代码部分,避免并排除任何和所有内存分配以及实际测量执行中类似的超长和嘈杂部分:
// ------------------------------------------------------------<SuT>-START
tic()
for i=1:N
v[i]=fetch(remotecall(simple,2,i,1,vt_0,ct_0))
c[i]=fetch(remotecall(simple,3,i,2,vt_0,ct_0))
vt_0=v[i]
ct_0=c[i]
end
toc()
// ------------------------------------------------------------<SuT>-FINISH