Вызов функций при использовании параллельного программирования

У меня просто довольно простой вопрос об использовании MPI в программе на C++. Действительно, возьмем этот пример:

#include <iostream>
#include <sstream>
#include <cblas.h>
#include <cmath>

using namespace std;

#include <mpi.h>

void multiply(double* x,double* y,int tai,double dot){
    for(int i=0; i<tai;i=i+1){
        dot=dot+x[i]*y[i];
    }
}

int main(int argc, char* argv[]) {
    const int n=32;
    int rank;
    int size;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    int tai=n/size;
    double* x=new double[tai];
    double* y=new double[tai];
    srand(time(0)+rank);

    for(int i=0;i<tai;i=i+1){
        x[i]=(double)rand()/RAND_MAX*10;
        y[i]=(double)rand()/RAND_MAX*10;
    }
    double dot=0;
    multiply(x,y,tai,dot);
    double ddot;
    MPI_Reduce(&dot, &ddot, 1, MPI_DOUBLE, MPI_SUM,0, MPI_COMM_WORLD);
    if (rank==0){
        cout<<"product:"<<ddot<<endl;
    }
    MPI_Finalize();
    return 0;
}

Затем я вызываю свою функцию «умножение» в своей программе для умножения двух векторов, но, к сожалению, она возвращает начальное значение «точки» (которое в основном равно 0).

Я просто хотел бы знать, есть ли что-нибудь особенное в вызове функции при параллельном программировании.

PS: Я знаю, что вся программа работает, так как она дает мне хорошие результаты, когда я напрямую умножаю свои 2 вектора в функции "main".

multiply ничего не возвращает (его тип возврата - void, и, похоже, он не имеет выходных параметров). Можете ли вы показать минимальный воспроизводимый пример, чтобы мы могли понять, как вы его называете?
Angew is no longer proud of SO 14.03.2018 21:21

Последовательные отступы значительно упрощают понимание кода.

Andrew Henle 14.03.2018 21:34

Спасибо за ваши ответы. Я только что отредактировал свой вопрос, чтобы показать простой пример того, как я его использую.

Eric Ailantes 14.03.2018 21:37

Пожалуйста, пожалуйста, используйте правильный отступ.

Cris Luengo 14.03.2018 21:50

Это не написано на C.

JGroven 14.03.2018 23:02
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
5
78
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Помимо предоставленного кода, имеющего проблемы, ответ на ваш вопрос - нет, каждый элемент обработки будет выполнять функцию, как он называется, но, возможно, вы не хотите, чтобы каждый элемент обработки выполнял весь точечный продукт, и вам было бы лучше выключить использование scatterv и gatherv для разделения программы; или, может быть, каждый элемент обработки имеет свои собственные уникальные векторы, которые позже уменьшаются или добавляются, и все в порядке. Обязательно используйте типы MPI.

Ответ принят как подходящий

Начальное значение dot не меняется, потому что оно передается по значению. Копия dot создается при передаче в multiply, и это версия, которая изменяется. Если вы хотите, чтобы multiply изменил переменную dot и сохранил изменения вне функции multiply, передайте dot по ссылке.

void multiply(double* x, double* y, int tai, double& dot);

Тот факт, что вы используете MPI, не влияет на это поведение.

Действительно, сейчас это работает. Большое спасибо.

Eric Ailantes 14.03.2018 21:50

Другие вопросы по теме