标签: parallel-processing

并行长期运行任务的时间优化

介绍

我正在使用一个复杂的外部库,我试图在一大堆项目上执行它的功能.该库没有公开一个好的异步接口,所以我坚持使用一些非常老式的代码.

我的目标是优化完成一批处理所需的时间,并演示问题而不必包含我在下面创建的实际第三方库的近似问题

问题

给定非异步操作,您可以提前知道操作的"大小"(即复杂性):

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,并且具有相当高的并行性并且肯定有效 - 但是必须有一种方法来优化它们,所以一些最大的首先开始.

为了进一步说明问题,如果我们采取一个超简化的例子

  • 1个大小为10的任务 …

c# parallel-processing

5
推荐指数
1
解决办法
114
查看次数

在REPL中的Scala中具有java.util.concurrent._的死锁

我在学习Paul Chiusano和Runar Bjanarson的著作“ Scala中的函数编程”(第7章-纯函数并行性)时遇到了以下情况。

    package fpinscala.parallelism

    import java.util.concurrent._
    import language.implicitConversions


    object Par {
      type Par[A] = ExecutorService => Future[A]

      def run[A](s: ExecutorService)(a: Par[A]): Future[A] = a(s)

      def unit[A](a: A): Par[A] = (es: ExecutorService) => UnitFuture(a) // `unit` is represented as a function that returns a `UnitFuture`, which is a simple implementation of `Future` that just wraps a constant value. It doesn't use the `ExecutorService` at all. It's always done and can't be cancelled. Its `get` method simply returns the value …
Run Code Online (Sandbox Code Playgroud)

java parallel-processing scala java.util.concurrent scala-repl

5
推荐指数
1
解决办法
148
查看次数

教堂中的正交递归对分(Barnes-Hut算法)

我正在Chapel中实现Barnes-Hut n体仿真的分布式版本。我已经实现了GitHub上可用的顺序和共享内存版本。

我正在遵循此处概述的算法(第7章):

  1. 执行正交递归二等分并分配主体,以使每个过程的工作量相等
  2. 在每个过程上构造本地必不可少的树
  3. 计算力量和推进机构

我对如何在C / MPI中实现MPI_Allreduce用于二等分和简单消息传递以在进程之间进行通信(用于主体传输)有一个很好的想法。这也是MPI_Comm_split一个非常方便的功能,可让我在ORB的每个步骤中拆分进程。

我在使用Chapel提供的并行/分布式结构执行ORB时遇到了一些麻烦。我需要某种方式来汇总(减少)跨流程(在Chapel中的语言环境)的工作,将流程分为多个组,并进行流程间的通信以转移主体。

对于在教堂中如何实施此建议,我将不胜感激。如果另一种方法对Chapel更好,那也很好。

parallel-processing chapel

5
推荐指数
1
解决办法
226
查看次数

读取大型Excel xlsx文件的最快方法?是否并行化?

我的问题是:

  • 将大型(ish).xlsx Excel文件读入R的最快方法是什么?10到200 MB的xlsx文件,多张纸。

  • 可以使用某种并行处理吗,例如,每个核心读取多页Excel文件的一张纸?

  • 还有其他可以执行的优化吗?

到目前为止,我所了解的(以及我尚未了解的):

  • 如果要从旋转磁盘读取数据,正如我所愿,并行处理实际上可能会减慢读取速度,因为多个进程试图从同一个文件读取数据。但是,并行处理可能有助于转换和推断数据类型?不知道readxl从磁盘读取(我认为是IO绑定)还是转换数据类型(我估计是CPU绑定)花了多少钱。
  • 对于SSD驱动器,可能有所不同。如果有很大的改进,我可能会将数据复制到SSD驱动器并从那里读取。
  • data.table :: fread可以加快文本文件的读取速度(尽管我不完全理解为什么),但是它不能用于excel文件-可以吗?
  • 我从这个答案中了解到readxl往往比openxlsx

我只对表格数据感兴趣;我对Excel格式,图表,文本标签或任何其他类型的数据都不感兴趣。

我可能希望导入整洁的小标题,但不一定。然后,我需要将表导出到Microsoft SQL Server中。

背景知识:我主要使用Python,并且对R完全陌生。使用Python 读取大型Excel文件非常缓慢。我已经看到R的readxl速度比Python快pandas(在15页xlsx上,每页有10,000行和32列:readxl 5.6秒,熊猫33秒),这太棒了!但是,我仍然想了解是否有任何方法可以使导入速度更快。我可以使用R读取文件,将其导出到SQL,然后使用从SQL中读取的Python继续其余的工作流程。

我认为转换为CSV并不是最好的选择,尤其是当readxl远比Python快得多时;基本上转换为csv所需的时间可能比我从csv读取而不是excel节省​​的时间要长。另外,至少对于Python(我不太了解R是否足以使用readxl对其进行全面测试)而言,使用xlsx推断数据类型要比使用csv更好。

我的代码(欢迎提出任何批评或建议):

library(readxl)
library(tidyverse)
library(tictoc)


this.dir <- dirname(parent.frame(2)$ofile)
setwd(this.dir)

tic("readxl")

path <- "myfile.xlsx"
sheetnames <- excel_sheets(path)
mylist <- lapply(excel_sheets(path), read_excel, path = path)

names(mylist) <- sheetnames
toc()
Run Code Online (Sandbox Code Playgroud)

parallel-processing r readxl

5
推荐指数
1
解决办法
892
查看次数

如何在dask中并行化groupby()?

我试过了:

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不起作用?

谢谢

parallel-processing pandas dask pandas-groupby

5
推荐指数
1
解决办法
237
查看次数

并行映射和并行for循环之间的区别

当我阅读Julia的多核并行计算文档时,我注意到同时存在并行映射pmap和for-loop @distributed for

从文档中可以看出,“ Julia pmap是为每个函数调用都需要大量工作的情况而设计的。相比之下,Julia @distributed for可以处理每次迭代很小的情况”。

pmap和 之间有什么区别@distributed for?为什么@distributed for要花大量时间进行缓慢工作?

谢谢

parallel-processing distributed pmap julia

5
推荐指数
2
解决办法
179
查看次数

如何使用C ++标准库并行处理Plain 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::vectorint因此我要遍历一系列索引。但是那将是荒谬的。

  • 我可以使用std::generate_n一些虚拟输出迭代器,该迭代器丢弃分配的所有内容。由于我认为没有可用,因此std我必须自己编写完整的虚拟迭代器。无论如何,这当然是愚蠢的。拥有正确的索引可能需要使用a进行手动跟踪,std::atomic<int>因为您不了解当前的索引。

  • 我真的没有容器可以循环。我的意思是,在这些函数的深处都有容器,但是重组所有内容只是为了让我可以在此循环中对某些容器使用迭代器,这是不可能的。

  • 搜寻了15分钟的不同描述后,我却一无所获。

有什么方法可以将最简单和最基本的for循环与<algorithm>不涉及愚蠢的废话的工具相匹配?

c++ parallel-processing for-loop

5
推荐指数
1
解决办法
534
查看次数

如何在Clojure中实现并行逻辑或提前终止

我想定义一个谓词,以某些谓词与相应的输入作为输入(它们可以作为懒惰的调用序列提供),并行运行它们并计算逻辑或结果,以使谓词调用终止返回时true,整个计算也终止(return true)。

除了提供时间优化之外,这还有助于避免在某些情况下不终止(某些谓词调用可能不会终止)。实际上,undefined该谓词将非终止解释为第三个值,它模拟Kleene K3逻辑 (初始居中Kleene代数中的连接)的or运算。

Haskell家族的情况与类似。Clojure中有任何(最好是简单的)方法可以做到这一点吗?

编辑:在阅读评论后,我决定添加一些说明。

(a)首先,在线程池用尽之后发生的事情不太重要。我认为创建一个足以满足我们需求的线程池是一个合理的约定。

(b)最关键的要求是谓词调用开始并行运行,并且一旦谓词调用终止返回true,所有其他运行线程都会被中断。预期的行为是:

  • 如果有谓词调用返回true:并行或返回true
  • 否则,如果有一个谓词调用不终止:并行或不终止
  • 否则:平行或返回 false

换句话说,它的行为就像在由下式给出的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

5
推荐指数
1
解决办法
233
查看次数

并行Seq对执行语句序列有何好处?

我有一个使用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

但是我担心它是否会导致性能下降。(如果地图实现中保留了额外的代码以保留其顺序,则这会带来性能开销)。

请建议我该怎么做。

parallel-processing scala par

5
推荐指数
1
解决办法
58
查看次数

从R中的parallelSVM复制结果的问题

我无法设置种子值来从中获得可重复的结果parallelSVM()

 library(e1071)
 library(parallelSVM)

 data(iris)
 x <- subset(iris, select = -Species)
 y <- iris$Species

set.seed(1)
model       <- parallelSVM(x, y)
parallelPredictions <- predict(model, x)

set.seed(1)
model2       <- parallelSVM(x, y)
parallelPredictions2 <- predict(model2, x)

all.equal(parallelPredictions,parallelPredictions2) 

Run Code Online (Sandbox Code Playgroud)

我知道这不是为多核操作设置种子值的正确方法,但是我不知道该怎么做。

我知道使用时有一个选项,mclapply但这对我的情况没有帮助。


编辑:
我已经发现通过改变功能的溶液trainSample()内的parallelSVM具有tracedoRNG包装用于与种子foreach循环。

有人知道更好的解决方案吗?

parallel-processing r machine-learning reproducible-research random-seed

5
推荐指数
1
解决办法
72
查看次数