C++:逐个条目评估自己的数学函数(函数数组等多维分析)

C++: Evaluate own mathematical function (function-array like multidimensional analysis) entry-wise

本文关键字:函数 数组 多维分析 自己的 评估 C++      更新时间:2023-10-16

嘿,我想评估一个数学函数(用户定义),该函数在数组中返回多个值(该函数是基于向量的函数 f:R^n->R^m,具有 n 个输入坐标和 m 个输出函数),C++某些参数,例如:

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()的人只需要编写一个函数,您将负责委派多个调用,确保它们具有正确的数据来处理,并收集结果。

根据评论进行更新

在您的情况下,如果计算vals的每个成员所需的操作不同,则用户必须通过所需的索引参数化my_func();正如您在double my_func(const mxArray *point, const unsigned & index)建议的那样,请注意它现在如何返回单个双精度值而不是整个结果数组。或者为每个索引提供不同的my_func(); double my_func_n(const mxArray *point) .

然后,您可以从任意数量的不同线程调用此函数或一组函数,并获得单个结果以进行进一步计算。我们忽略了许多与同时读取/写入数据有关的并发问题,这些问题需要考虑。

一般的询问建议

在研究使用 GPU 进行多任务处理之前,请查看 CPU 上的标准多线程(我建议使用 Boost 线程库来帮助:http://www.boost.org/)。一旦你看到了线程是如何创建和使用的,你可能会发现你更了解你可以用它们做什么以及如何去做。

如果您将数学函数应用于非常大的矩阵或向量,并且可以使用某些图形函数的硬件实现来实现数学结果,则使用 GPU 进行多任务处理将变得更加有用。还有其他库支持GPGPU(通用GPU)编程,例如OpenCL,Nvidia的CUDA或ATI的Stream。看看这些库提供了什么,让您了解它们对您的情况的适用性。