Я пытаюсь установить общение "все-к-одному" вне очереди. В основном у меня есть несколько массивов с плавающей запятой одинакового размера, идентифицируемых по целочисленному идентификатору.
Каждое сообщение должно выглядеть так:
<int id><float array data>
На стороне получателя он точно знает, сколько существует массивов, и, таким образом, устанавливает точное количество recv. Получив сообщение, он анализирует идентификатор и помещает данные в нужное место. Проблема в том, что сообщение может быть отправлено из любых других процессов принимающему процессу. (например, производители имеют структуру очереди работ и обрабатывают любой идентификатор, доступный в очереди.)
Поскольку MPI гарантирует только P2P при доставке заказа, я не могу просто поместить целочисленный идентификатор и данные FP в два сообщения, иначе получатель не сможет сопоставить идентификатор с данными. MPI также не позволяет передавать два типа данных за одну отправку.
Я могу думать только о двух подходах.
1) Получатель имеет массив размера m (источник [m]), где m - количество отправляющих узлов. Отправитель сначала отправляет идентификатор, затем данные. Получатель сохраняет идентификатор в источник [i] после получения целочисленного сообщения от отправителя i. Получив массив FP от отправителя i, он проверяет источник [i], получает идентификатор и перемещает данные в нужное место. Это работает, потому что MPI гарантирует упорядоченную связь P2P. Это требует, чтобы получатель сохранял информацию о состоянии каждого отправителя. Что еще хуже, если один процесс отправки может иметь два идентификатора, отправленных перед данными (например, многопоточность), этот механизм не будет работать.
2) Обработайте id и FP как байты и скопируйте их в буфер отправки. Отправьте их как MPI_CHAR, а получатель вернет их в целое число и массив FP. Затем мне нужно оплатить дополнительную стоимость копирования вещей в байтовый буфер на стороне отправителя. Общий временный буфер также растет по мере увеличения числа потоков в процессе MPI.
Ни один из них не является идеальным решением. Я не хочу ничего блокировать внутри процесса. Интересно, есть ли у кого-нибудь из вас лучшие предложения.
Изменить: код будет запущен в общем кластере с infiniband. Машины будут распределены случайным образом. Поэтому я не думаю, что сокеты TCP смогут мне здесь помочь. К тому же IPoIB выглядит дорого. Мне нужна полная скорость 40 Гбит / с для связи, и процессор должен выполнять вычисления.