我最近写了很多关于并行计算和编程的文章,我注意到在并行计算方面有很多模式出现.注意到Microsoft已经发布了一个库以及Microsoft Visual C++ 2010社区技术预览版(名为Parallel Patterns Library),我想知道你一直在使用和遇到的常见并行编程模式有哪些值得记住?当你用C++编写并行程序时,你是否有任何习惯用法和你似乎不断弹出的模式?
我目前的任务是优化蒙特卡罗模拟,该模拟根据一组Obligors计算资本充足率数据.
它运行大约10倍太慢,无法生产,需要数量或每日运行.此外,结果数字的粒度需要在某个阶段提升到桌面可能的书本水平,我给出的代码基本上是一个原型,由半生产能力的业务部门使用.
该应用程序目前是单线程的,所以我需要使它多线程,可能看看System.Threading.ThreadPool或Microsoft Parallel Extensions库但我在这家银行的服务器上受限于.NET 2所以我可能不得不考虑这个人的端口,http://www.codeproject.com/KB/cs/aforge_parallel.aspx.
我正在尽力让他们升级到.NET 3.5 SP1,但这是在这种规模的组织中的一项重要练习,在合同时间框架内可能无法实现.
我使用dotTrace的试用版(http://www.jetbrains.com/profiler)描述了该应用程序.还有哪些好的剖析器?免费的?
大量的执行时间用于生成均匀的随机数,然后将其转换为正态分布的随机数.他们正在使用C#Mersenne twister实现.我不确定他们在哪里获得它,或者它是最好的方法来实现这个(或最佳实现)来生成统一的随机数.然后将其转换为正态分布版本以供计算使用(我还没有深入研究过翻译代码).
使用以下内容的经验是什么?
http://www.qlnet.org(Quantlib的C#端口)或
您知道的任何替代方案?我是C#开发人员,所以更喜欢C#,但C++的包装应该不是问题,是吗?
也许更快地利用C++实现.我认为这些库中的一些库将具有最快的方法来直接生成正态分布的随机数,而无需转换步骤.此外,他们可能还有一些其他功能,将有助于后续计算.
此外,它所使用的计算机是四核Opteron 275,8 GB内存,但Windows Server 2003 Enterprise 32位.我应该建议他们升级到64位操作系统吗?任何支持这一决定的文章的链接都将非常感激.
无论如何,任何建议和帮助你都非常感激.
我正在尝试并行化一个旧的Makefile.
实际上,我需要确保在编译过程开始之前调用某些生成器脚本不是并行的.
始终在编译之前调用生成器.有没有办法在makefile中建立一个有点关键的部分?
Makefile很乱,我不想在这里发帖.
我正在尝试使用此处概述的方法将C++类包装在matlab mex包装器中.基本上,我有一个初始化mex文件,它返回一个C++对象句柄:
handle = myclass_init()
Run Code Online (Sandbox Code Playgroud)
然后我可以将它传递给另一个myclass_amethod使用句柄调用类方法的mex文件(例如),然后最终myclass_delete释放C++对象:
retval = myclass_amethod(handle, parameter)
myclass_delete(handle)
Run Code Online (Sandbox Code Playgroud)
为了便于使用,我把它包装在一个MATLAB类中:
classdef myclass < handle
properties(SetAccess=protected)
cpp_handle_
end
methods
% class constructor
function obj = myclass()
obj.cpp_handle_ = myclass_init();
end
% class destructor
function delete(obj)
myclass_delete(obj.cpp_handle_);
end
% class method
function amethod(parameter)
myclass_amethod(obj.cpp_handle_, parameter);
end
end
end
Run Code Online (Sandbox Code Playgroud)
这在非并行代码中工作正常.但是,只要我从一个内部调用它parfor:
cls = myclass();
parfor i = 1:10
cls.amethod(i)
end
Run Code Online (Sandbox Code Playgroud)
我得到一个段错误,因为类的副本是在parfor循环中(在每个worker中)制作的,但由于每个worker都是一个单独的进程,因此不会复制C++对象实例,从而导致指针无效.
我最初尝试检测每个类方法何时在parfor循环中运行,并且在这些情况下也重新分配C++对象.但是,由于无法检查是否已为当前工作程序分配了对象,因此会导致多次重新分配,然后只有一次删除(当工作人员退出时)导致内存泄漏(请参阅附录中的附录)问题详情).
matlab.mixin.Copyable在C++中,处理它的方法是复制构造函数(这样只有在复制包装器MATLAB类时才重新分配C++对象).快速搜索会显示matlab.mixin.Copyable类类型,它似乎提供了所需的功能(即MATLAB句柄类的深层副本).因此,我尝试了以下方法:
classdef myclass …Run Code Online (Sandbox Code Playgroud) 我有OpenMP的问题.MSVS编译器抛出"pragma omp atomic有不正确的形式".我不知道为什么.代码:(程序使用积分方法指定PI编号)
#include <stdio.h>
#include <time.h>
#include <omp.h>
long long num_steps = 1000000000;
double step;
int main(int argc, char* argv[])
{
clock_t start, stop;
double x, pi, sum=0.0;
int i;
step = 1./(double)num_steps;
start = clock();
#pragma omp parallel for
for (i=0; i<num_steps; i++)
{
x = (i + .5)*step;
#pragma omp atomic //this part contains error
sum = sum + 4.0/(1.+ x*x);
}
pi = sum*step;
stop = clock();
// some printf to show results
return …Run Code Online (Sandbox Code Playgroud) 我是IPython的新手,想在运行IPython并行集群功能时将中间结果打印到stdout.(我知道有多个进程,这可能会破坏输出,但这很好 - 它只是用于测试/调试,而我正在运行的进程足够长,以至于不太可能发生此类冲突.)我检查了IPython的文档,但找不到并行化函数打印的示例.基本上,我正在寻找一种方法将子进程的打印输出重定向到主stdout,IPython相当于
subprocess.Popen( ... , stdout=...)
Run Code Online (Sandbox Code Playgroud)
在流程内打印不起作用:
rc = Client()
dview = rc()
def ff(x):
print(x)
return x**2
sync = dview.map_sync(ff,[1,2,3,4])
print('sync res=%s'%repr(sync))
async = dview.map_async(ff,[1,2,3,4])
print('async res=%s'%repr(async))
print(async.display_outputs())
Run Code Online (Sandbox Code Playgroud)
回报
sync res=[1, 4, 9, 16]
async res=[1, 4, 9, 16]
Run Code Online (Sandbox Code Playgroud)
因此计算正确执行,但函数ff中的print语句永远不会打印,即使返回所有进程也是如此.我究竟做错了什么?如何让"打印"工作?
python printing parallel-processing ipython ipython-parallel
我有一个简单的问题来解决(或多或少)
,如果我看蟒蛇多的教程,我看到的是一个过程,应开始或多或少是这样的:
from multiprocessing import *
def u(m):
print(m)
return
A=Process(target=u,args=(0,))
A.start()
A.join()
Run Code Online (Sandbox Code Playgroud)
它应该打印0但没有打印.相反,它永远挂在了A.join().
如果我手动启动你这样做的功能
A.run()
Run Code Online (Sandbox Code Playgroud)
它实际上在shell上打印0但它不能同时工作
,例如以下代码的输出:
from multiprocessing import *
from time import sleep
def u(m):
sleep(1)
print(m)
return
A=Process(target=u,args=(1,))
A.start()
print(0)
Run Code Online (Sandbox Code Playgroud)
应该是
0
1
但实际上是
0
如果我在最后一行之前添加
A.run()
Run Code Online (Sandbox Code Playgroud)
然后输出变为
1
0
这对我来说似乎有点困惑......
如果我尝试加入这个过程,它会永远等待.
但是,如果它可以帮助给我一个答案
我的操作系统为Mac OS X 10.6.8
使用Python版本是3.1和3.3
我的电脑有1个英特尔酷睿i3处理器
--Update--
我注意到这种奇怪的行为只有在从IDLE启动程序时才会出现,如果我从终端运行程序一切正常,那么这个问题必须连接到一些IDLE错误.
但是来自终端的runnung程序甚至更奇怪:使用范围(100000000)之类的东西激活我所有计算机的内存,直到程序结束; 如果我记得很清楚这不应该发生在python 3中,只有在较旧的python版本中.我希望这些新信息可以帮助你给出答案
- 更新2--
即使我不从我的进程执行输出,也会发生错误,因为设置此:
def u():
return
Run Code Online (Sandbox Code Playgroud)
作为进程的目标,然后启动它,如果我尝试加入进程,空闲等待永远
我使用python'multiprocessing'模块在多个内核上运行单个进程,但我希望并行运行几个独立的进程.对于ex - 进程一解析大文件,进程二找不到文件中的模式,进程三进行一些计算; 可以并行运行具有不同参数集的所有三个不同的处理吗?
def Process1(largefile):
Parse large file
runtime 2hrs
return parsed_file
def Process2(bigfile)
Find pattern in big file
runtime 2.5 hrs
return pattern
def Process3(integer)
Do astronomical calculation
Run time 2.25 hrs
return calculation_results
def FinalProcess(parsed,pattern,calc_results):
Do analysis
Runtime 10 min
return final_results
def main():
parsed = Process1(largefile)
pattern = Process2(bigfile)
calc_res = Process3(integer)
Final = FinalProcess(parsed,pattern,calc_res)
if __name__ == __main__:
main()
sys.exit()
Run Code Online (Sandbox Code Playgroud)
在上面的伪代码Process1中,Process2和Process3是单核过程,即它们不能在多个处理器上运行.这些过程按顺序进行,取2 + 2.5 + 2.25hrs = 6.75小时.是否可以并行运行这三个过程?这样它们可以在不同的处理器/内核上同时运行,并且当大部分时间(Process2)完成时,我们将转移到Final Process.
我将衷心感谢您的帮助.
AK
目前我的解决方案是:
exec('php file.php >/dev/null 2>&1 &');
Run Code Online (Sandbox Code Playgroud)
并在file.php中
if (posix_getpid() != posix_getsid(getmypid()))
posix_setsid();
Run Code Online (Sandbox Code Playgroud)
我有什么方法可以用exec做到这一点?
请注意,我知道Parallel.Invoke()用于任务同步.我的问题是:
有没有办法使用Parallel.Invoke这样的调用匿名方法,其中调用不等待执行完成?
我认为并行执行(或并行调用)的重点是不必等待任务完成.如果你想等待一段代码完成执行,而不是使用Parallel.Invoke,为什么不直接调用代码呢?我想我只是不明白Parallel.Invoke的意思.文档只说明它的作用,但没有提到任何用例,这比直接调用代码更有用.