C ++: оценивать собственную математическую функцию (массив функций, например, многомерный анализ), начиная с начала - PullRequest
0 голосов
/ 09 мая 2011

Привет, я хочу оценить математическую функцию (определенную пользователем), которая возвращает несколько значений в массиве (эта функция является векторной функцией 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;
}

В настоящее время я делаю это на процессоре.Поэтому я вызываю функцию один раз и возвращаю массив со всеми значениями функции.Поскольку я хочу распараллелить это сейчас на GPU, я подумал о том, как это сделать.

Полагаю, было бы глупо полностью вычислять my_func () в каждом потоке, поскольку каждый поток вычисляет весь массив функций. Это правильное предположение?

Можно ли было бы как-нибудь удобно рассчитать только n-й элемент массива функций и вернуть его, чтобы 5 потоков могли легко вычислить функцию- массив параллельно, а не один процессор, вычисляющий его полностью «в одиночку»?

Единственный способ, которым я мог думать, был:

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%% и не знать, является ли это хорошим способом сделать это... Итак, вопрос в том, найдется ли лучший способ справиться с этой проблемой?

1 Ответ

1 голос
/ 09 мая 2011

Когда вы говорите «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).

Затем вы можете вызывать эту функцию или набор функций из любого числа потоков, сколько захотите, и получить один результат для дальнейших вычислений.Однако мы игнорируем многие проблемы параллелизма, связанные с одновременным чтением / записью данных, о которых нужно подумать.

Общие рекомендации по многозадачности

Прежде чем приступить к многозадачности с помощью графического процессора,посмотрите на стандартную многопоточность на процессоре (я рекомендую Boost Thread Libraries, чтобы помочь: http://www.boost.org/). После того, как вы увидите, как создаются и используются потоки, вы можете лучше понять, что вы можете с ними делать и как с этим справляться.Делая это.

Многозадачность с графическим процессором становится более полезной, если вы применяете математические функции к очень большим матрицам или векторам, и для достижения математического результата можно использовать аппаратные реализации определенных графических функций.для поддержки программирования GPGPU (GPU общего назначения), такого как OpenCL, Nvidia CUDA или ATI Stream. Посмотрите, что предоставляют эти библиотеки, чтобы дать вам представление о том, насколько они применимы к вашей ситуации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...