微软是否有可能在虚拟机执行时制作F#程序,或者更有可能在编译时,检测程序是用函数式语言构建的,并自动更好地并行化?
现在我相信没有这样的努力来尝试执行一个程序,该程序作为单线程程序自动构建为多线程程序.
也就是说,开发人员会编写单线程程序.并且编译器会吐出一个多线程的编译程序,并在需要时使用互斥锁和同步.
这些优化是否会在进程线程计数中的任务管理器中可见,还是会低于该级别?
这是我的一本CS教科书中的一个问题.我很茫然.我不明白为什么它必然会导致并行计算.有人想指出我正确的方向吗?
我需要快速遍历一棵树,我想并行完成.我宁愿使用并行扩展而不是手动旋转一堆线程.
我当前的代码看起来像这样:
public void Traverse(Node root)
{
var nodeQueue = new Queue<Node>();
nodeQueue.Enqueue(root);
while (nodeQueue.Count!=0)
{
var node = nodeQueue.Dequeue();
if (node.Property = someValue) DoSomething(node);
foreach (var node in node.Children)
{
nodeQueue.Enqueue(node);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我真的希望Parallel.ForEach有一个Parallel.While模拟.我遇到了Stephen Toub关于使用Parallel.ForEach实现Parallels Parallel的文章.如果正确读取它仍然无法工作,因为我正在改变我试图迭代的队列.
我是否需要使用任务工厂和递归(这有风险吗?)?还是有一些我忽略的简单解决方案?
编辑:@svick
该树有超过250,000个节点.现在最大深度是14个节点,包括根.
根目录下有大约500个节点,之后的平衡具有相当随机的分布.我很快就会得到更好的分布统计数据.
@Enigmativity:
是的,许多用户同时修改了树,但我通常会为树或子树提供共享读锁,或允许脏读.
对node.Children的调用可以被认为是原子的.
DoSomething实际上是几个代理之一,对于一些昂贵的操作,我可能会收集节点的快照列表并在遍历之外处理它们.
我意识到我应该看一般情况(遍历的子树而不是整个树.)为此,我在树的每个节点上运行遍历并查看总时间.
我为每个遍历算法使用了Parallel.ForEach(nodes,Traverse),其中节点包含所有~250k节点.这模拟(某种程度上)许多用户同时请求许多不同的节点.
00256ms广度优先顺序
00323ms广度优先连续工作(我将静态计数器增加为"工作")
01495ms Kirks第一个回答
01143ms Svicks第二个答案
00000ms Recursive Single Threaded在60s后没有完成
00000ms电子书的答案在60年代后没有完成
@Enigma,我想我可能会以某种方式搞砸你的算法,因为它似乎应该更快.
结果令我惊讶的是至少可以说.为了让自己相信编译器并没有神奇地优化遍历,我不得不在广度第一顺序中添加一些工作.
对于头部的单次遍历,并行化第一级仅具有最佳性能.但几乎没有,这个数字有所改善,因为我向第二级添加了更多节点(2000而不是500).
有没有办法fork()在Perl中实现非阻塞/异步执行(没有'ing)?
我曾经是一名Python开发人员多年...... Python拥有非常棒的'Twisted'框架允许这样做(使用DEFERREDs.当我运行搜索以查看Perl中是否有任何内容可以执行相同操作时,我遇到了POE框架 - 看起来与我正在搜索的内容"相近".但是......花了一些时间阅读文档并"玩"代码后,我反对"墙" - 这是限制性的(来自POE) ::会话文档):
回调不是先发制人的.只要一个人正在运行,就不会派遣其他人.这称为协作式多任务处理.每个会话必须通过返回中央调度内核进行协作.
这种限制基本上违背了异步/并行/非阻塞执行的目的 - 通过限制在任何给定时刻执行的只有一个回调(代码块).当另一个回调已经在运行时,没有其他回调可以开始运行!
所以......在Perl中有没有办法实现多任务(并行,非阻塞,异步执行代码)而不用fork()- 类似于Python中的DEFERREDs?
我理解使用subprocess是调用外部命令的首选方式.
但是如果我想在parall中运行几个命令,但是限制生成的进程数呢?困扰我的是我无法阻止子进程.例如,如果我打电话
subprocess.Popen(cmd, stderr=outputfile, stdout=outputfile)
Run Code Online (Sandbox Code Playgroud)
然后该过程将继续,无需等待cmd完成.因此,我无法将其包装在multiprocessing图书馆的工作人员中.
例如,如果我这样做:
def worker(cmd):
subprocess.Popen(cmd, stderr=outputfile, stdout=outputfile);
pool = Pool( processes = 10 );
results =[pool.apply_async(worker, [cmd]) for cmd in cmd_list];
ans = [res.get() for res in results];
Run Code Online (Sandbox Code Playgroud)
然后每个工人将在产生子流程后完成并返回.所以我无法真正限制subprocess使用生成的进程数Pool.
什么是限制子过程数量的正确方法?
我有一个包含我想要运行的命令行的文件.该文件包含大约2,000行.
我有8个核心可用.是否可以解析文件并启动8个进程,然后在其中一个程序完成时从文件中执行另一个进程?我希望这一直持续到文件结束.
如果我运行此测试:
var r = new Random();
var ints = new int[13];
Parallel.For(0, 2000000, i => {
var result = r.Next(1, 7) + r.Next(1, 7);
ints[result] += 1;
});
Run Code Online (Sandbox Code Playgroud)
我得到以下结果:
2: 92,14445
3: 0,41765
4: 0,62245
5: 0,82525
6: 1,04035
7: 1,25215
8: 1,0531
9: 0,8341
10: 0,6334
11: 0,4192
12: 0,2109
Run Code Online (Sandbox Code Playgroud)
当我使用常规For:
for (int i = 0; i < 2000000; i++) {
var result = r.Next(1, 7) + r.Next(1, 7);
ints[result] += 1;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
2: 2,7797
3: 5,58645
4: …Run Code Online (Sandbox Code Playgroud) 我想将一些视图从任何位置移动到屏幕中心并平行缩放.如果这太复杂,顺序翻译和缩放也是可以接受的.但我无法实现.我认为这是枢轴点的问题.但抱歉,我没有找到解决办法.请帮忙.也许这对开发游戏的人来说很容易,我什么也没做.
以下是我的代码:
private void moveViewToScreenCenter( final View view ){
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics( dm );
int statusBarOffset = dm.heightPixels - rootLayout.getMeasuredHeight();
int originalPos[] = new int[2];
view.getLocationOnScreen( originalPos );
int xDelta = (dm.widthPixels - view.getMeasuredWidth())/2 - originalPos[0];
int yDelta = (dm.heightPixels - view.getMeasuredHeight())/2 + statusBarOffset - originalPos[1];
AnimationSet animSet = new AnimationSet(true);
animSet.setFillAfter(true);
animSet.setDuration(1000);
animSet.setInterpolator(new BounceInterpolator());
TranslateAnimation translate = new TranslateAnimation( 0, xDelta , 0, yDelta);
animSet.addAnimation(translate);
ScaleAnimation scale = new ScaleAnimation(1f, …Run Code Online (Sandbox Code Playgroud) 我正在启动一个子进程并在运行时解析stdout而不必等待它完成解析stdout.
for sample in all_samples:
my_tool_subprocess = subprocess.Popen('mytool {}'.format(sample),shell=True, stdout=subprocess.PIPE)
line = True
while line:
myline = my_tool_subprocess.stdout.readline()
#here I parse stdout..
Run Code Online (Sandbox Code Playgroud)
在我的脚本中,我多次执行此操作,实际上取决于输入样本的数量.
这里的主要问题是每个子进程都是一个程序/工具,它在运行时使用1个CPU 100%.这需要一些时间......每次输入可能需要20-40分钟.
我想什么来实现的,是设置一个游泳池,队列(我不知道这是怎么确切的术语)在同时运行N最大的子进程的工作过程.所以我可以最大化性能,而不是按顺序进行.
因此,执行流程,例如最多4个作业池应该是:
如果我能实现这一点,我真的不知道如何识别哪个样本子流程已完成.此时,我不需要识别它们,因为每个子进程按顺序运行,并且我解析stdout,因为子进程正在打印stdout.
这非常重要,因为我需要识别每个子流程的输出并将其分配给它的相应输入/样本.
我想在一个大清单上做一个平行地图.代码看起来有点像这样:
big_list
|> Stream.map(&Task.async(Module, :do_something, [&1]))
|> Stream.map(&Task.await(&1))
|> Enum.filter filter_fun
Run Code Online (Sandbox Code Playgroud)
但是我正在检查Stream实现,据我所知,它Stream.map结合了函数并将组合函数应用于流中的元素,这意味着序列是这样的:
在这种情况下,它不会并行执行.我是对的还是我错过了什么?
如果我是对的,那么这段代码呢?
Stream.map Task.async ...
|> Enum.map Task.await ...
Run Code Online (Sandbox Code Playgroud)
这是否会并行运行?
c# ×2
python ×2
subprocess ×2
android ×1
asynchronous ×1
bash ×1
c#-4.0 ×1
elixir ×1
f# ×1
moores-law ×1
nonblocking ×1
perl ×1
queue ×1
scale ×1
stdout ×1
system ×1