你好, 我想在 C++ 中评估一个数学函数(用户定义的),它在一个数组中返回几个值(这个函数是一个基于 vector 的函数 f:R^n->R^m,具有 n 个输入坐标和 m 个输出函数)参数,例如:
double *my_func(const mxArray *point)
{
double *dat = mxGetPr(point);
double *vals = new double[ 3 ];
vals[0] = dat[0]*dat[0]*dat[0]*dat[0]*dat[0];
vals[1] = sin(dat[0])*dat[1]*dat[2]*dat[2]*cos(dat[1]);
vals[2] = exp(dat[0])*sin(dat[0])*dat[3];
double *pnt = vals;
return pnt;
}
目前我在 CPU 上执行此操作。所以我调用函数一次并取回一个包含所有函数值的数组。因为我现在想在 GPU 上并行化它,所以我考虑了如何去做。
我认为在每个线程中完全评估 my_func() 是有点愚蠢,因为每个线程都会计算整个函数数组。 这是正确的假设吗?
是否有任何方法可以轻松地仅计算函数数组的第 n 个元素并将其返回,以便 5 个线程可以轻松地并行计算函数数组,而不是一个 CPU 完全“单独”计算它?
我能想到的唯一方法是:
double my_func0(const mxArray *point)
{
double *dat = mxGetPr(point);
return dat[0]*dat[0]*dat[0]*dat[0]*dat[0];
}
double my_func1(const mxArray *point)
{
double *dat = mxGetPr(point);
return sin(dat[0])*dat[1]*dat[2]*dat[2]*cos(dat[1]);
}
double my_func2(const mxArray *point)
{
double *dat = mxGetPr(point);
return exp(dat[0])*sin(dat[0])*dat[3];
}
等等...但这对于以后使用该程序的用户来说会很“不舒服”,因为如果他想扩展函数数组而不是仅仅修改一个 C++,他总是必须创建新的 C++ 函数-功能。另一个问题是:我必须动态调用该函数,因为函数的数量是“动态的”,因此我必须调用 my_func_%%i%%
而不是知道这是否是一个好方法......所以问题是是否有更好的方法来处理这个问题?
最佳答案
当您说“user_defined”时,我猜您的意思是其他人编写了 my_func()
然后您的代码调用了它?
如果是这种情况,请考虑并行运行对 my_func()
的多次调用,而不是试图将函数分解。这意味着编写 my_func()
的人只需编写一个函数,您将负责委托(delegate)多个调用,确保他们有正确的数据来处理,并收集结果。
根据评论更新
在您的情况下,如果计算 vals
的每个成员所需的操作不同,则用户要么必须通过所需的索引参数化 my_func()
;正如您所建议的那样 double my_func(const mxArray *point, const unsigned & index)
,请注意它现在如何返回单个 double 值而不是整个结果数组。或者为每个索引提供不同的my_func()
; double my_func_n(const mxArray *point)
。
然后,您可以根据需要从尽可能多的不同线程调用此函数或函数集,并获得单个结果以进行进一步计算。我们忽略了许多并发问题,但是同时处理需要考虑的读/写数据。
一般多任务处理建议
在研究 GPU 的多任务处理之前,先了解一下 CPU 上的标准多线程(我推荐 Boost 线程库来提供帮助:http://www.boost.org/)。一旦您了解了线程的创建和使用方式,您可能会发现您可以更好地理解您可以使用它们做什么以及您将如何去做。
如果您将数学函数应用于非常大的矩阵或 vector ,并且可以使用某些图形函数的硬件实现来实现数学结果,那么使用 GPU 进行多任务处理会变得更加有用。还有其他库支持 GPGPU(通用 GPU)编程,例如 OpenCL、Nvidia 的 CUDA 或 ATI 的 Stream。查看这些库提供的内容,了解它们如何适用于您的情况。
关于C++:评估自己的数学函数(像多维分析一样的函数数组)entry-wise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5940453/