2013-03-05 8 views
1

Извините, если этот вопрос является общим или тривиальным, я не очень хорошо знаком с MPI, так что несите меня.MPI синхронизировать матрицу векторов

У меня есть матрица векторов. Каждый вектор пуст или содержит несколько элементов.

std::vector<someStruct*> partitions[matrix_size][matrix_size]; 

При запуске программы каждый процесс будет иметь одни и те же данные в этой матрице, но, как код прогрессирует каждый процесс может удалить несколько элементов из некоторых векторов и поместить их в других векторах.

Итак, когда я достигаю барьера, мне нужно как-то убедиться, что каждый процесс имеет последнюю версию этой матрицы. Большая проблема заключается в том, что каждый процесс может манипулировать любыми или всеми векторами.

Как я буду следить за тем, чтобы каждый процесс имел правильную обновленную матрицу после барьера?

EDIT: Прошу прощения, что я не был чист. Каждый процесс может перемещать один или несколько объектов на другой вектор, но только один процесс может перемещать каждый объект. Другими словами, каждый процесс имеет список объектов, которые он может перемещать, но матрица может быть изменена всеми. И два процесса не могут перемещать один и тот же объект.

+0

Если каждый процессор манипулирует потенциально любым элементом, как вы решаете, что такое «правильная обновленная матрица»? –

+0

Прошу прощения, я не был ясен. Каждый процесс может перемещать один или несколько объектов на другой вектор, но только один процесс может перемещать каждый объект. – Chippen

ответ

1

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

Еще одна вещь: векторы указателей обычно представляют собой довольно плохую идею, так как вам необходимо вручную управлять памятью. Если вы можете использовать C++ 11, используйте вместо этого std::unique_ptr или std::shared_ptr (в зависимости от вашей семантики) или используйте Boost, который предоставляет очень похожие средства.

И, наконец, представление матрицы в виде массива фиксированного размера с фиксированными размерами явно плохо. Во-первых: размер матрицы фиксирован. Во-вторых: соседние строки не обязательно хранятся в непрерывной памяти, замедляя вашу программу, как сумасшедшую (буквально это могут быть порядки величин). Вместо этого представляем матрицу как линейный массив размером Nrows*Ncols, а затем индексируем элементы как Nrows*i + j, где Nrows - это количество строк и i и j - это индексы строк и столбцов соответственно. Если вместо этого вы не хотите использовать хранилище столбцов, обратитесь к элементам по адресу i + Ncols*j. Вы можете обернуть это манипулирование индексами встроенными функциями, которые имеют практически нулевые служебные данные.

+0

Благодарим вас, я не уверен, как отправлять эти инструкции только корневому, но я, вероятно, могу это понять. Что касается матричной части, то на данный момент мне не нужна скорость, но я согласен, что это будет лучшее решение. Я попробую это! – Chippen

+0

Вы действительно должны взглянуть на [документацию MPI] (http://www.mpi-forum.org/docs/docs.html). Это действительно читаемо и содержит много примеров. –

+0

В C элементы в статических 2D-массивах хранятся смежно (по очереди, определенные в 8.3.4). Поэтому, если вы обращаетесь к ним надлежащим образом, они не являются проблемой производительности. (Есть и другие проблемы.) – Zulan

1

Я хотел бы предложить, чтобы выложить данные по-разному:

Каждый процесс имеет карту своих объектов и их положение в матрице. Как это реализовано, зависит от того, как вы идентифицируете объекты. Если все локальные объекты пронумерованы, вы можете просто использовать vector<pair<int,int>>.

Относитесь к тому, что в качестве основной структуры вы управляете и связываете эту структуру с MPI_Allgather (каждый процесс отправляет данные всем остальным процессам, в конце каждый имеет все данные). Если вам нужен быстрый поиск по координатам, вы можете создать кеш.

Это может быть или не работать хорошо. Другие оптимизации (например, совместное использование транзакций) полностью зависят от ваших объектов и операций, которые вы выполняете на них.

Смежные вопросы