我正在编写一个使用OpenMP进行矩阵乘法的程序,为了方便缓存,实现乘法A x B(转置)行X行而不是经典的A x B行x列,以获得更好的缓存效率.这样做我遇到了一个有趣的事实,对我来说是不合逻辑的:如果在这段代码中我并行化extern循环,程序比我将OpenMP指令放在最内层循环中慢,在我的计算机中,时间是10.9对8.1秒.
//A and B are double* allocated with malloc, Nu is the lenght of the matrixes
//which are square
//#pragma omp parallel for
for (i=0; i<Nu; i++){
for (j=0; j<Nu; j++){
*(C+(i*Nu+j)) = 0.;
#pragma omp parallel for
for(k=0;k<Nu ;k++){
*(C+(i*Nu+j))+=*(A+(i*Nu+k)) * *(B+(j*Nu+k));//C(i,j)=sum(over k) A(i,k)*B(k,j)
}
}
}
Run Code Online (Sandbox Code Playgroud) parallel-processing performance loops openmp matrix-multiplication
简单的问题.
对于任何给定的算法,您如何确定MaxDegreeOfParallelism的最佳值?需要考虑哪些因素以及权衡取舍?
.net c# parallel-processing multithreading task-parallel-library
我们遇到一个令人尴尬的并行问题 - 我们运行一个单个程序的大量实例,每个程序都有不同的数据集; 我们只需将应用程序多次提交到具有不同参数的批处理队列即可.
但是,由于有大量工作,并非所有工作都完成.它似乎不是队列中的问题 - 所有作业都已启动.
问题似乎是,随着应用程序的大量实例运行,许多作业大致同时完成,因此所有人都试图在几乎同时将其数据写入并行文件系统.
然后问题似乎是程序无法写入文件系统并以某种方式崩溃,或者只是坐在那里等待写入,批处理队列系统在等待太长时间后就会终止作业.(从我收集的问题来看,大多数未能完成的工作,如果不是全部,都不会留下核心文件)
调度磁盘写入以避免此问题的最佳方法是什么?我提到我们的程序是令人尴尬的并行突出显示每个进程都不知道其他进程的事实 - 他们不能互相交谈以某种方式安排他们的写入.
虽然我有程序的源代码,但我们希望解决问题而不必在可能的情况下修改它,因为我们不维护或开发它(加上大多数注释都是意大利语).
我对此事有一些想法:
与此同时,我需要纠缠我的主管以获取有关错误本身的更多信息 - 我从未亲自遇到过它,但我还没有将程序用于大量数据集(尚未).
如果它有用:我们在HPC系统上使用SGE(Sun GridEngine)批处理队列系统运行Solaris.文件系统是NFS4,存储服务器也运行Solaris.HPC节点和存储服务器通过光纤通道链路进行通信.
c filesystems parallel-processing fortran embarrassingly-parallel
假设我有一些Python代码,如下所示:
input = open("input.txt")
x = (process_line(line) for line in input)
y = (process_item(item) for item in x)
z = (generate_output_line(item) + "\n" for item in y)
output = open("output.txt", "w")
output.writelines(z)
Run Code Online (Sandbox Code Playgroud)
此代码从输入文件中读取每一行,通过多个函数运行它,并将输出写入输出文件.现在我知道函数process_line,process_item并且generate_output_line永远不会相互干扰,让我们假设输入和输出文件位于不同的磁盘上,这样读写就不会相互干扰.
但Python可能不知道这些.我的理解是Python将读取一行,依次应用每个函数,并将结果写入输出,然后只有在将第一行发送到输出后才会读取第二行,这样第二行就不会进入管道直到第一个退出.我是否正确理解该程序将如何流动?如果这是它的工作方式,是否有任何简单的方法可以使多个行同时在管道中,以便程序并行读取,写入和处理每个步骤?
我有一个非托管的C++ DLL,我的.NET应用程序通过p/invoke使用它.我需要从这个DLL的方法相当耗时,我想并行化方法调用.问题是它使用了一堆静态和全局变量,因此它不是线程安全的(并且不能更改).我的计划是通过并行调用多个AppDomain中的非托管DLL来克服这个非线程安全问题.
我可以从多个AppDomain中调用非托管代码而不会出现任何问题,只要我不并行执行,但只要我并行调用,我就会得到一个AccessViolationException.我正在使用Parallel.For()来进行并行调用.
是否可以通过简单地从多个AppDomain进行调用来使非线程安全的非托管DLL"线程安全"?
我在C#中实现了一个非常基本的线程:
private Thread listenThread;
public void startParser()
{
this.listenThread = new Thread(new ThreadStart(checkingData));
this.listenThread.IsBackground = true;
this.listenThread.Start();
}
private void checkingData()
{
while (true)
{
}
Run Code Online (Sandbox Code Playgroud)
}
然后我立即获得100%的CPU.我想检查传感器数据是否在while(true)循环内读取.为什么会这样?
提前致谢.
我想 - 由于晦涩的原因,你不应该质疑 - 开始锁定方法,然后在另一个方法中结束.不知何故喜欢:
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解决方案持开放态度.:)
我的线程如何工作的模型是有些ThreadManager给每个线程转一圈.当它是一个线程时,它会执行几行代码.
暂停一个线程,是不是只有ThreadManager(暂时)停止允许该线程转弯?
要中止一个线程,不能ThreadManager只是永远不会给那个线程另一个转弯?
有什么问题?
我在网上找到了一段代码并对其进行了一些修改以了解它是如何工作的,但现在我遇到了问题,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不等待计算所有结果并且程序结束就像程序中没有那行代码(几毫秒之后)?
我的目标是具有并行折叠功能.起初,它似乎很容易实现,这就是我的想法:
首先根据核心数(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] …