标签: parallel-processing

以不同方法开始和完成锁定

我想 - 由于晦涩的原因,你不应该质疑 - 开始锁定方法,然后在另一个方法中结束.不知何故喜欢:

object mutex = new object();

void Main(string[] args)
{
    lock (mutex)
    {
        doThings();
    }
}
Run Code Online (Sandbox Code Playgroud)

会有如下行为:

object mutex = new object();

void Main(string[] args)
{
    Foo();
    doThings();
    Bar();
}

void Foo()
{
    startLock(mutex);
}

void Bar()
{
    endlock(mutex);
}
Run Code Online (Sandbox Code Playgroud)

当然,问题是lock关键字以块语法工作.我知道锁并不意味着像这样使用,但我不仅仅对S/O的创意和hacky解决方案持开放态度.:)

.net c# parallel-processing multithreading locking

7
推荐指数
1
解决办法
1107
查看次数

暂停/中止线程为什么不好?

我的线程如何工作的模型是有些ThreadManager给每个线程转一圈.当它是一个线程时,它会执行几行代码.

暂停一个线程,是不是只有ThreadManager(暂时)停止允许该线程转弯?

要中止一个线程,不能ThreadManager只是永远不会给那个线程另一个转弯?

有什么问题?

.net c# parallel-processing multithreading thread-safety

7
推荐指数
1
解决办法
313
查看次数

ContinueWhenAll不等待所有任务完成

我在网上找到了一段代码并对其进行了一些修改以了解它是如何工作的,但现在我遇到了问题,ContinueWhenAll因为它不等待所有任务完成:

List<Task> tasks = new List<Task>();
for (int i = 0; i < 20; i++)
{
    int j = i;
    var compute = Task.Factory.StartNew(() => results.Add(DoSomething(j)));
    tasks.Add(compute);
}
Run Code Online (Sandbox Code Playgroud)

我正在使用此代码将所有任务添加到列表中.DoSomething函数计算一些结果并将它们添加到BlockingCollection.我有另一个显示功能,它将所有添加的结果写入BlockingCollection控制台.

我已经使用此代码等待所有任务完成,但看起来它不会等待它们,因为程序"Press any key to continue"在启动后的几毫秒内显示标准消息.(程序完成需要~20秒)

Task.Factory.ContinueWhenAll(tasks.ToArray(), result => results.CompleteAdding());
Run Code Online (Sandbox Code Playgroud)

但是,如果我添加Task.WaitAll(consume)到程序结束,程序工作正常:

var consume = Task.Factory.StartNew(() => display(results));
//results = BlockingCollection that I mentioned 
Run Code Online (Sandbox Code Playgroud)

据我所知,该程序没有足够的时间显示所有结果,BlockingCollection但仍有足够的时间显示一些,同时等待所有任务完成.

有人可以解释我为什么Task.Factory.ContinueWhenAll不等待计算所有结果并且程序结束就像程序中没有那行代码(几毫秒之后)?

c# parallel-processing task

7
推荐指数
1
解决办法
1万
查看次数

比这更通用的parfoldr

我的目标是具有并行折叠功能.起初,它似乎很容易实现,这就是我的想法:

首先根据核心数(numCapabilities)将输入列表分解为分区.然后将foldr应用于每个分区,这将导致每个分区的折叠值列表.然后在该列表上再次执行折叠以获取最终值.

    listChunkSize = numCapabilities

    chunk n [] = []
    chunk n xs = ys : chunk n zs
      where (ys,zs) = splitAt n xs

    parfoldr f z [] = z
    parfoldr f z xs = res
      where
            parts = chunk listChunkSize xs
            partsRs = map (foldr f z) parts `using` parList rdeepseq
            res = foldr f z partsRs
Run Code Online (Sandbox Code Playgroud)

上面的代码不起作用,因为很明显foldr的定义(a -> b -> b) -> b -> [a] -> b意味着输入列表类型(好,可以)与累加器和结果类型不同.

例如,

1)foldr (+) 0 [1..10] …

parallel-processing haskell

7
推荐指数
1
解决办法
1056
查看次数

ParallelEnumerable.Range vs Enumerable.Range.AsParallel?

ParallelEnumerable.Range 和 之间有什么区别Enumerable.Range(...).AsParallel()

ParallelEnumerable.Range 创建范围分区(最适合cpu时间等于foreach项的操作)

Enumerable.Range(...).AsParallel()可能作为range或执行的地方chunk

有任何性能差异吗?我什么时候应该使用哪个?

.net c# linq parallel-processing

7
推荐指数
1
解决办法
1797
查看次数

Dekker算法混淆的变体

这个程序执行两个不同的线程,并告诉我谁是"种族"的赢家.

出乎意料的是,有时两条线程"赢"(我预计有人或没有人获胜).这是预期的行为吗?为什么?我显然在这里缺少一些基本的东西.

class Program
{
    public volatile static int a = 0; 
    public volatile static int b = 0;

    public static void Main()
    {
        for(int i = 0; i < 1000; i++)
        {
            a = 0; 
            b = 0;

            Parallel.Invoke(delegate { a = 1; if (b == 0) Console.WriteLine("A wins"); },
                            delegate { b = 1; if (a == 0) Console.WriteLine("B wins"); });

            Console.WriteLine(System.Environment.NewLine);

            Thread.Sleep(500);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

结果:

A wins

B wins

A wins
B wins

A wins

...
Run Code Online (Sandbox Code Playgroud)

c# parallel-processing concurrency multithreading

7
推荐指数
1
解决办法
701
查看次数

PHP中的多线程,多卷曲爬虫

大家好再次!

我们需要一些帮助来在我们的抓取工具中开发和实现多卷曲功能.我们有一大堆"要扫描的链接",我们循环使用Foreach.

让我们使用一些伪代码来理解逻辑:

    1) While ($links_to_be_scanned > 0).
    2) Foreach ($links_to_be_scanned as $link_to_be_scanned).
    3) Scan_the_link() and run some other functions.
    4) Extract the new links from the xdom.
    5) Push the new links into $links_to_be_scanned.
    5) Push the current link into $links_already_scanned.
    6) Remove the current link from $links_to_be_scanned.
Run Code Online (Sandbox Code Playgroud)

现在,我们需要定义最大数量的并行连接,并能够并行地为每个链接运行此过程.

我知道我们必须创建$ links_being_scanned或某种队列.

我真的不确定如何处理这个问题,说实话,如果有人能提供一些片段或想法来解决它,我将不胜感激.

提前致谢!克里斯;

扩展:

我刚刚意识到,多卷曲本身并不是棘手的部分,而是请求后每个链接完成的操作量.

即使在muticurl之后,我最终也必须找到一种方法来并行运行所有这些操作.下面描述的整个算法必须并行运行.

所以现在重新思考,我们必须做这样的事情:

  While (There's links to be scanned)
  Foreach ($Link_to_scann as $link)
  If (There's less than 10 scanners running)
  Launch_a_new_scanner($link)
  Remove the link …
Run Code Online (Sandbox Code Playgroud)

php parallel-processing curl fork fsockopen

7
推荐指数
1
解决办法
4968
查看次数

多核CPU:编程技术,以避免令人失望的可扩展性

我们刚刚购买了一台32核的Opteron机器,我们获得的加速有点令人失望:超过大约24个线程我们看不到加速(实际上总体上变慢)并且在大约6个线程之后它变得非常线性.

我们的应用程序非常适合线程:我们的工作分为大约170,000个小任务,每个任务可以单独执行,每个任务需要5-10秒.它们都是从大小约为4Gb的相同内存映射文件中读取的.它们偶尔写入它,但每次写入可能有10,000次读取 - 我们只是在170,000个任务的每一个末尾写入一些数据.写入受锁保护.分析表明锁不是问题.线程在非共享对象中使用大量JVM内存,并且它们对共享JVM对象的访问非常少,而且只有一小部分访问涉及写入.

我们在Linux上使用NUMA进行Java编程.我们有128Gb RAM.我们有2个Opteron CPU(型号6274),每个16核.每个CPU有2个NUMA节点.在英特尔四核(即8核)上运行的相同工作几乎线性地扩展到8个线程.

我们已经尝试将只读数据复制到每个线程一个,希望大多数查找可以是NUMA节点的本地查找,但是我们没有观察到它的加速.

有32个线程,'top'显示CPU的74%"us"(用户)和大约23%的"id"(空闲).但是没有睡眠,几乎没有磁盘i/o.有24个线程,我们可以获得83%的CPU使用率.我不确定如何解释'空闲'状态 - 这是否意味着'等待内存控制器'?

我们尝试打开和关闭NUMA(我指的是需要重启的Linux级别设置),并没有看到任何区别.当启用NUMA时,'numastat'仅显示约5%的'分配和访问未命中'(95%的缓存未命中是NUMA节点的本地).[编辑:]但是添加"-XX:+ useNUMA"作为java命令行标志给了我们10%的提升.

我们的一个理论是我们最大化内存控制器,因为我们的应用程序使用了大量的RAM,我们认为有很多缓存未命中.

我们可以做些什么(a)加速我们的程序以接近线性可扩展性,或(b)诊断正在发生的事情?

另外:(c)我如何解释"顶部"结果 - "空闲"是否意味着"在内存控制器上被阻止"?(d)Opteron与Xeon的特性有何不同?

parallel-processing cpu multicore numa

7
推荐指数
1
解决办法
909
查看次数

Groovy/Grails GPARS:如何并行执行2次计算?

我是GPARS库的新手,目前正在我们的软件中实现它.

对我来说,使用它而不是像普通的groovy方法一样没问题

[..].each{..} 
-> 
[..].eachParallel{..}
Run Code Online (Sandbox Code Playgroud)

但我想知道如何并行化2个返回值的任务.

没有GPARS,我会这样做:

List<Thread> threads = []
def forecastData
def actualData  
threads.add(Thread.start {
    forecastData = cosmoSegmentationService.getForecastSegmentCharacteristics(dataset, planPeriod, thruPeriod)
})

threads.add(Thread.start {
    actualData = cosmoSegmentationService.getMeasuredSegmentCharacteristics(dataset, fromPeriod, thruPeriodActual)
})

threads*.join()

// merge both datasets
def data = actualData + forecastData
Run Code Online (Sandbox Code Playgroud)

但是(如何)可以用GparsPool完成?

parallel-processing groovy gpars

7
推荐指数
1
解决办法
3080
查看次数

OpenMP:在线程之间共享数组

今天是个好日子!

我正在进行分子动力学模拟,最近我开始尝试并行实现它.乍一看,一切看起来都很简单:在最耗时的循环之前编写#pragma omp parallel for directive.但实际上,这些循环中的函数在数组上运行,或者确切地说,在属于我的类的对象的数组上运行,该数组包含有关此系统的粒子系统和函数的所有信息,因此当我添加#时pragma指令在最耗时的循环之一之前,尽管我的2核4线程处理器已满载,但计算时间实际上增加了几倍.

为了解决这个问题,我写了另一个更简单的程序.该测试程序执行两个相同的循环,一个并行,第二个循环 - 串行.测量执行这两个循环所花费的时间.结果让我感到惊讶:每当第一个循环并行计算时,其计算时间与串行模式(分别为1500和6000毫秒)相比有所下降,但第二个循环的计算时间急剧增加(15000对6000连续).

我尝试使用private()和firstprivate()子句,但结果是一样的.不应该自动共享并行区域之前定义和初始化的每个变量吗?如果在另一个向量上执行,第二个循环的计算时间恢复正常:vec2,但是为每次迭代创建一个新向量显然不是一个选项.我也尝试将vec1的实际更新放到#pragma omp关键区域,但这也没有任何好处.没有帮助添加Shared(vec1)子句.

如果你能指出我的错误并展示正确的方法,我将不胜感激.

是否有必要将私有(i)放入代码中?

这是测试程序:

#include "stdafx.h"
#include <omp.h>
#include <array>
#include <time.h>
#include <vector>
#include <iostream>
#include <Windows.h>
using namespace std;
#define N1  1000
#define N2  4000
#define dim 1000

int main(){
    vector<int>res1,res2;
    vector<double>vec1(dim),vec2(N1);
    clock_t t, tt;
    int k=0;
    for( k = 0; k<dim; k++){
        vec1[k]=1;
    }

    t = clock();

    #pragma omp parallel 
        {
        double temp; 
        int i,j,k;
        #pragma omp for private(i)
            for( i = 0; i<N1; i++){
                for(j = …
Run Code Online (Sandbox Code Playgroud)

parallel-processing multithreading openmp

7
推荐指数
1
解决办法
4843
查看次数