我希望澄清我对.NET多线程的理解,特别是哪些.NET方法创建的线程可能会在多处理器/核心系统中的不同处理器或内核上同时执行.
在.NET TPL框架中,您可以使用Parallel.Invoke或Task.Factory.StartNew方法来实现某种并行性.
我的理解是,在这两种情况下.NET都会创建新的任务(在Parallel.Invoke的幕后),.NET环境然后在后台分配给托管线程,然后将其分配给线程,CPU可以分配给不同的线程核心或处理器取决于工作负载.这两种方法的主要区别在于语义 - Parallel.Invoke执行多个任务并等待它们完成; Task.Factory.StartNew在后台启动一个新任务.在这两种情况下,实际工作可以在不同的核心或处理器上完成.根据任务并行库(TPL).
我有一位同事确信只有Parallel.Invoke方法允许线程在不同的核心/处理器上执行,而Task.Factory.StartNew启动一个新线程但该线程只能在一个核心/处理器上调度 - 所以实际上并没有给出并行性.
我找不到任何明确说明是否属于这种情况的文件或文章.我的同事向我介绍了我正在查看的相同文章,例如基于任务的异步编程,我认为这可以验证我的理解,但我的同事认为验证了他的.
文档有时使用术语"并行处理"参考Parallel.Invoke和"异步任务"参考"Task.Factory.StartNew",但据我所知,同样的事情发生在背景中关于分配到多处理器/核心.
任何人都可以帮助澄清情况,如果可能的话,链接到文档/文章.
我知道这听起来像是要求与同事一起解决争论,但我真的想澄清我是否正确理解这一点.
我有一个实时的Linux桌面应用程序(用C编写),我们正在移植到ARM(4核Cortex v8-A72 CPU).在架构上,它结合了高优先级显式pthread(其中6个)和一对GCD(libdispatch)工作队列(一个并发和另一个串行).
我的担忧有两个方面:
select声明中)parallel-processing operating-system arm multiprocessing grand-central-dispatch
我有一个项目,我在Haskell中构建一个决策树.生成的树将具有多个彼此独立的分支,因此我认为它们可以并行构建.
该DecisionTree数据类型被限定如下所示:
data DecisionTree =
Question Filter DecisionTree DecisionTree |
Answer DecisionTreeResult
instance NFData DecisionTree where
rnf (Answer dtr) = rnf dtr
rnf (Question fil dt1 dt2) = rnf fil `seq` rnf dt1 `seq` rnf dt2
Run Code Online (Sandbox Code Playgroud)
这是构造树的算法的一部分
constructTree :: TrainingParameters -> [Map String Value] -> Filter -> Either String DecisionTree
constructTree trainingParameters trainingData fil =
if informationGain trainingData (parseFilter fil) < entropyLimit trainingParameters
then constructAnswer (targetVariable trainingParameters) trainingData
else
Question fil <$> affirmativeTree <*> negativeTree `using` …Run Code Online (Sandbox Code Playgroud) 我正在使用一个复杂的外部库,我试图在一大堆项目上执行它的功能.该库没有公开一个好的异步接口,所以我坚持使用一些非常老式的代码.
我的目标是优化完成一批处理所需的时间,并演示问题而不必包含我在下面创建的实际第三方库的近似问题
给定非异步操作,您可以提前知道操作的"大小"(即复杂性):
public interface IAction
{
int Size { get; }
void Execute();
}
Run Code Online (Sandbox Code Playgroud)
鉴于此动作有3种变体:
public class LongAction : IAction
{
public int Size => 10000;
public void Execute()
{
Thread.Sleep(10000);
}
}
public class MediumAction : IAction
{
public int Size => 1000;
public void Execute()
{
Thread.Sleep(1000);
}
}
public class ShortAction : IAction
{
public int Size => 100;
public void Execute()
{
Thread.Sleep(100);
}
}
Run Code Online (Sandbox Code Playgroud)
您如何优化这些操作的长列表,以便在以某种并行方式运行时,整个批处理尽可能快地完成?
天真的,你可以把整个批次扔到一个Parallel.ForEach,并且具有相当高的并行性并且肯定有效 - 但是必须有一种方法来优化它们,所以一些最大的首先开始.
为了进一步说明问题,如果我们采取一个超简化的例子
我正在Chapel中实现Barnes-Hut n体仿真的分布式版本。我已经实现了GitHub上可用的顺序和共享内存版本。
我正在遵循此处概述的算法(第7章):
我对如何在C / MPI中实现MPI_Allreduce用于二等分和简单消息传递以在进程之间进行通信(用于主体传输)有一个很好的想法。这也是MPI_Comm_split一个非常方便的功能,可让我在ORB的每个步骤中拆分进程。
我在使用Chapel提供的并行/分布式结构执行ORB时遇到了一些麻烦。我需要某种方式来汇总(减少)跨流程(在Chapel中的语言环境)的工作,将流程分为多个组,并进行流程间的通信以转移主体。
对于在教堂中如何实施此建议,我将不胜感激。如果另一种方法对Chapel更好,那也很好。
我试过了:
df.groupby('name').agg('count').compute(num_workers=1)
df.groupby('name').agg('count').compute(num_workers=4)
Run Code Online (Sandbox Code Playgroud)
他们花相同的时间,为什么num_workers不起作用?
谢谢
当我阅读Julia的多核并行计算文档时,我注意到同时存在并行映射pmap和for-loop @distributed for。
从文档中可以看出,“ Julia pmap是为每个函数调用都需要大量工作的情况而设计的。相比之下,Julia @distributed for可以处理每次迭代很小的情况”。
pmap和 之间有什么区别@distributed for?为什么@distributed for要花大量时间进行缓慢工作?
谢谢
我不得不问这个问题,这有点愚蠢,但我只是找不到一种毫不费力的方法来做到这一点。
我有以下循环:
for (int i = 0; i < count; ++i) {
if (myFunc(i))
continue;
myOtherFunc(i);
}
Run Code Online (Sandbox Code Playgroud)
与OpenMP并行实现这一点很简单:只需#pragma omp parallel for在循环之前添加即可。
我想将OMP(及其不同的计划)的性能与MSVC的并行<algorithms>实现(即使用C ++ 17执行策略)进行比较。最直接的想法是使用std::for_each,但是我想不出一种好方法将这个超简单for循环转换成可以在其上施加<algorithm>执行策略的任何适当的东西。
值得注意的是,你不能只是做
std::for_each(std::execution::par, 0, count, [](int i){ /*...*/ });
Run Code Online (Sandbox Code Playgroud)
因为您必须提供迭代器(即i在取消引用时会产生参数的东西)。
我可以std::iota进入std::vector,int因此我要遍历一系列索引。但是那将是荒谬的。
我可以使用std::generate_n一些虚拟输出迭代器,该迭代器丢弃分配的所有内容。由于我认为没有可用,因此std我必须自己编写完整的虚拟迭代器。无论如何,这当然是愚蠢的。拥有正确的索引可能需要使用a进行手动跟踪,std::atomic<int>因为您不了解当前的索引。
我真的没有容器可以循环。我的意思是,在这些函数的深处都有容器,但是重组所有内容只是为了让我可以在此循环中对某些容器使用迭代器,这是不可能的。
搜寻了15分钟的不同描述后,我却一无所获。
有什么方法可以将最简单和最基本的for循环与<algorithm>不涉及愚蠢的废话的工具相匹配?
我想定义一个谓词,以某些谓词与相应的输入作为输入(它们可以作为懒惰的调用序列提供),并行运行它们并计算逻辑或结果,以使谓词调用终止返回时true,整个计算也终止(return true)。
除了提供时间优化之外,这还有助于避免在某些情况下不终止(某些谓词调用可能不会终止)。实际上,undefined该谓词将非终止解释为第三个值,它模拟Kleene K3逻辑
(初始居中Kleene代数中的连接)的or运算。
Haskell家族的情况与此类似。Clojure中有任何(最好是简单的)方法可以做到这一点吗?
编辑:在阅读评论后,我决定添加一些说明。
(a)首先,在线程池用尽之后发生的事情不太重要。我认为创建一个足以满足我们需求的线程池是一个合理的约定。
(b)最关键的要求是谓词调用开始并行运行,并且一旦谓词调用终止返回true,所有其他运行线程都会被中断。预期的行为是:
true:并行或返回truefalse换句话说,它的行为就像在由下式给出的3元素晶格中的加入false< undefined< true,与undefined代表非终止。
(c)并行或应该能够接受许多谓词和许多谓词输入(每个对应于一个谓词)作为输入。但是,如果将延迟序列作为输入,那就更好了。然后,命名并行或pany(对于“任何并行”),我们可以进行如下调用:
(pany (map (comp eval list) predicates inputs))(pany (map (comp eval list) predicates (repeat input)))(pany (map (comp eval list) (repeat predicate) inputs)) 相当于 (pany (map predicate (unchunk inputs)))最后,我认为,很自然地要求这样的事情pany,例如双重pall,机制或机制,以构建此类尽早终止的并行约简,以易于实现,甚至内置于面向并行性的语言(如Clojure)中。
parallel-processing logic functional-programming clojure terminate
我有一个使用List.par的小程序
val x = List(1,2,3,4,5).par.map(y => {
Thread.sleep(2000)
println(y)
y + 1
})
println(x)
Run Code Online (Sandbox Code Playgroud)
输出:
3
1
4
5
2
ParVector(2, 3, 4, 5, 6)
Run Code Online (Sandbox Code Playgroud)
数字并行打印,但是返回值始终保持其顺序。
我的目标是并行执行对SQL数据库的一系列插入语句。
目前,我正在理解。随着语句数量的增加,我想使用ParSeq。
但是我担心它是否会导致性能下降。(如果地图实现中保留了额外的代码以保留其顺序,则这会带来性能开销)。
请建议我该怎么做。