我有一个AWS实例.我想运行一堆任务,一些内存和CPU密集.理想情况下,我想计算每项任务的时间信息.如果我连续运行它们,它会计算准确的计时信息,但速度很慢.如果我并行运行它们,整个事情就会更快,但是单个任务的速度会更慢,正如壁时间和线程CPU时间所报告的那样.
随着线程数量增加到CPU数量,这种减速会增加
粗略检查ghc-events-analyze并+RTS -s暗示减速的来源(不出所料)GC暂停.使用RTS选项显示+RTS -qg -qb -qa -A256m(禁用并行GC,禁用负载平衡GC,禁用线程迁移以及增加GC分配区域)可以改善这一点,但并不能完全消除它.
我正在使用线程运行forkIO,但除了打印进度信息之外,线程是独立且纯粹的.我正在使用parallel-io来管理正在运行的线程的数量,但是当我简单地尝试一种更常规的方法来获得一个固定的线程池和一个任务队列时,我仍然遇到了这个问题.
有关如何调试的任何建议?
编辑:
@jberryman问了一个例子.每个任务看起来像下面的代码
computation params = do
!x <- force params
print $ "Starting computation on " ++ show params
t1 <- getCPUTime
!y <- fmap force $ do $
...some work with x ...
t2 <- getCPUTime
print $ "Finished computation on " ++ show params
return (t2 - t1, y)
Run Code Online (Sandbox Code Playgroud) parallel-processing multithreading garbage-collection haskell
据我所知,C++ 17将带有Parallelism.但是,我无法理解的是它是一种特定的硬件并行性(默认为CPU)?或者它可以扩展到具有多个计算单元的任何硬件?
换句话说,我们会看到类似于"nVidia C++标准编译器"的东西,它将编译要在GPU上执行的并行部分吗?
例如,它是OpenCL的一些标准替代品吗?
注意:当然,我不是在问"nVidia会这么做吗?".我在问C++ 17标准是否允许,以及理论上是否可行.
我有一个我想要并行执行的进程,但是由于一些奇怪的错误我失败了.现在我正在考虑组合,并计算主CPU上的失败任务.但是我不知道如何为.combine编写这样的函数.
怎么写?
我知道如何编写它们,例如这个答案提供了一个例子,但它没有提供如何处理失败的任务,也没有重复在主服务器上重复任务.
我会做的事情如下:
foreach(i=1:100, .combine = function(x, y){tryCatch(?)} %dopar% {
long_process_which_fails_randomly(i)
}
Run Code Online (Sandbox Code Playgroud)
但是,如何在.combine函数中使用该任务的输入(如果可以的话)?或者我应该在内部提供%dopar%返回标志或列表来计算它?
我可以改变我的循环
for (int i = 0; i < something; i++)
Run Code Online (Sandbox Code Playgroud)
至:
Parallel.For(0, something, i =>
Run Code Online (Sandbox Code Playgroud)
但是如何用这个循环做到这一点?:
for (i = 3; i <= something / 2; i = i + 2)
Run Code Online (Sandbox Code Playgroud)
谢谢你的回答.
我们使用更重量级的控制台应用程序,使用HTTP触发器和消费服务计划测试了Azure功能的横向扩展功能.所以我们期望通过扩展来实现并行执行.我们在新的AppDomain中执行控制台应用程序,因为funcion实例在同一进程中运行.在控制台应用程序中,我们在内存数据库中执行sqlite数据库操作.
首先我们只执行一次该功能,并测量执行时间.让它成为x :)我们不断开始增加并行线程的数量.我们经历过在这些情况下1个函数app实例的执行时间是x*num_of_threads.好像函数实例已被序列化并且不是并行执行的.
谢谢你的帮助.
编辑:我的应用程序的基本源代码:
using System.Net;
using System;
public static HttpResponseMessage Run(HttpRequestMessage req, TraceWriter log, ExecutionContext context)
{
string testThreadId = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "id", true) == 0)
.Value;
var funcId = context.InvocationId.ToString();
var homePath = Environment.GetEnvironmentVariable("HOME");
var folderName = Path.Combine(homePath,@"site\wwwroot\JanoRunTime2");
var fileName = Path.Combine(folderName,"AzureFunctionTest.exe");
var configFile = Path.Combine(folderName,"AzureFunctionTest.exe.config");
var setup = new AppDomainSetup();
setup.ApplicationBase = folderName;
setup.ConfigurationFile = configFile;
var newDomain = AppDomain.CreateDomain("JanoTestExecutorDomain_" + funcId, null, setup );
try{
newDomain.ExecuteAssembly(fileName, new []{testThreadId, funcId});
return req.CreateResponse(HttpStatusCode.OK …Run Code Online (Sandbox Code Playgroud) 我有以下代码:
myfun <- function() {
fun2()
return(1+1)
}
Run Code Online (Sandbox Code Playgroud)
我希望fun2()被调用,然后移到下一行而不等待结果。fun2函数不返回任何内容,我也不关心它何时完成,我只需要启动它即可。最好的方法是什么?并行进程,多线程,异步调用?任何代码示例,不胜感激。
我想学习并行编程以加速算法并选择Java.
我写了两个函数来对long数组中的整数求和- 一个简单的迭代遍历数组,第二个 - 将数组分成几个部分,并在分离的线程中汇总部分.
我预计使用两个线程的速度大约是2倍.但是,我得到的只是加速了24%.而且,使用更多线程,我在两个线程上没有任何改进(可能少于1%).我知道应该有线程创建/加入开销,但我想它不应该那么大.
你能解释一下,我错过了什么或代码中的错误在哪里?这是代码:
import java.util.concurrent.ThreadLocalRandom;
public class ParallelTest {
public static long sum1 (long[] num, int a, int b) {
long r = 0;
while (a < b) {
r += num[a];
++a;
}
return r;
}
public static class SumThread extends Thread {
private long num[];
private long r;
private int a, b;
public SumThread (long[] num, int a, int b) {
super();
this.num = num;
this.a = a;
this.b = b;
} …Run Code Online (Sandbox Code Playgroud) 在我的Fortran 95代码中,我有一系列嵌套的DO循环,整个过程需要大量的时间来计算,所以我想用OpenMP添加并行功能(gfortran -fopenmp用于编译/构建).
有一个主要的DO循环,运行1000次.
其中有一个子DO循环,运行100次.
其他几个DO循环嵌套在此中,迭代次数随着DO循环的每次迭代而增加(第一次一次,最后一次最多1000次).
例:
DO a = 1, 1000
DO b = 1, 100
DO c = 1, d
some calculations
END DO
DO c = 1, d
some calculations
END DO
DO c = 1, d
some calculations
END DO
END DO
d = d + 1
END DO
Run Code Online (Sandbox Code Playgroud)
一些嵌套的DO循环必须以串行方式运行,因为它们本身包含依赖关系(也就是说,循环的每次迭代都有一个包含上一次迭代的值的计算),并且在这种情况下不能轻易并行化.
我可以轻松地使没有任何依赖项的循环并行运行,如下所示:
d = 1
DO a = 1, 1000
DO b = 1, 100
DO c = 1, d
some calculations with dependencies
END …Run Code Online (Sandbox Code Playgroud) 有什么方法可以通过TPL节流来限制性能下降吗?
我有一个复杂的组件管道,并试图限制所需的内存需求。我从多个文件中并行读取,管道中的组件可能会从这些文件的随机部分中读取一些内容,其余组件则进行CPU绑定操作。
我使用通用测试方法将性能测试平台简化为这些测试。
private void TPLPerformaceTest(int generateNumbers, ExecutionDataflowBlockOptions transformBlockOptions)
{
var transformBlock = new TransformBlock<int, int>(i => i, transformBlockOptions);
var storedCount = 0;
var generatedCount = 0;
var store = new ActionBlock<int>(i => Interlocked.Increment(ref storedCount));
transformBlock.LinkTo(store);
transformBlock.Completion.ContinueWith(_ => store.Complete());
for (int i = 0; i < generateNumbers; i++)
{
transformBlock.SendAsync(i).Wait(); //To ensure delivery
Interlocked.Increment(ref generatedCount);
}
transformBlock.Complete();
store.Completion.Wait();
Assert.IsTrue(generatedCount == generateNumbers);
Assert.IsTrue(storedCount == generateNumbers);
}
Run Code Online (Sandbox Code Playgroud)
第一个没有节流。在我的CPU上,大约需要12秒钟才能完成,消耗约800MB的RAM,平均CPU利用率约为35%。
[Test]
public void TPLPerformaceUnlimitedTest()
{
var …Run Code Online (Sandbox Code Playgroud) c# parallel-processing performance performance-testing tpl-dataflow
给定一个由几个节点组成的集群,每个节点都托管多核处理器,在使用纯全MPI的节点和节点内的OpenMP/pthread 之间使用MPI有什么好处?如果我理解正确,如果我在一个节点上运行MPI程序并指示进程数等于内核数,那么我将在一个单独的内核上运行多个进程的一个诚实的并行MPI作业.那么为什么要使用节点内的线程和节点之间的MPI来进行混合并行化呢?在MPI + CUDA混合的情况下我毫无疑问,因为MPI不能使用GPU,但它可以使用CPU内核,那么为什么要使用线程呢?
c# ×2
r ×2
.net ×1
asynchronous ×1
azure ×1
c++ ×1
c++17 ×1
for-loop ×1
foreach ×1
fortran ×1
gfortran ×1
haskell ×1
java ×1
loops ×1
mpi ×1
openmp ×1
parallel.for ×1
performance ×1
tpl-dataflow ×1