2012-01-02 2 views
1

Я пытался найти ресурсы для лучшей производительности и масштабирования с передачей сообщений. Я слышал, что передача сообщения по значению вместо ссылки может быть лучшей масштабируемостью, так как она хорошо работает с настройками стиля NUMA и уменьшает конкуренцию для заданного адреса памяти.Темы - Message Passing

Я бы предположил, что передача сообщений на основе значений работает только с «меньшими» сообщениями. Что было бы «меньше» определено как? В какой момент ссылки будут лучше? Будет ли поток обрабатывать таким образом?

Я ищу полезные советы или ресурсы по этим вопросам.

С благодарностью :-)

P.S. Я работаю на C#, но я не думаю, что это так важно для таких вопросов дизайна.

+0

Что архитектуры вы используете? SMP, NUMA, кластер? – Tudor

+0

У меня сейчас нет проблемы, которую я сейчас решаю, но если бы я был, я бы нацелился на систему SMP + NUMA. – Bengie

+0

Я думаю, что единственный достаточный короткий ответ на эти вопросы: «Это зависит от вас», и единственный достаточный более длинный ответ на эти вопросы: «Оцените различные варианты вашей целевой системы и посмотрите, какую производительность вы получите за каждую ». Производительность зависит так много (и часто контр-интуитивно) от архитектурных деталей системы, на которой вы будете работать, что существует не так много общих правил, которые могли бы надежно применяться в разных системах. Разумеется, вы не должны доверять никакому полученному вами ответу, даже не измеряя его в своем приложении. –

ответ

3

Некоторые факторы, чтобы добавить к превосходному совету Джереми:

1) Передача по значению работает только эффективно для небольших сообщений. Если у данных есть неиспользуемая область [кеш-строки] в начале, чтобы избежать ложного обмена, вы уже приближаетесь к размеру, где более эффективная передача по ссылке.

2) Большие очереди означают большее пространство, занятое очередями, влияющее на использование памяти.

3) Копирование данных в/из больших структур очереди требует времени. Помимо фактического использования ЦП при перемещении данных, очередь остается заблокированной во время копирования. Это увеличивает конкуренцию в очереди и приводит к общему результату, зависящему от ширины очереди. Если в вашем коде есть какой-либо тупиковый потенциал, сохранение блокировок на длительные периоды не поможет.

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

5) Если сообщения передаются по ссылке и malloced/freed/newed/disposed/GC'd, это может привести к чрезмерному соперничеству с менеджером памяти и частым, расточительным GC. Обычно я использую фиксированные пулы сообщений, выделяемых при запуске, в частности, чтобы избежать этого.

6) Обработка байтовых потоков может быть неудобной при передаче по ссылке. Если байт-поток характеризуется частыми поставками одиночных байтов, передача по ссылке является разумной только в том случае, если байты чередуются. Это может привести к необходимости тайм-аутов для обеспечения своевременного отправки частично заполненных сообщений в следующий поток. Это приводит к осложнениям и задержкам.

7) Конструкции с перекрестными ссылками, по своей природе, скорее всего, будут протекать. Это может привести к увеличению времени тестирования и передозировки на valgrind - особенно болезненной зависимости (еще одна причина, по которой я использую пулы объектов фиксированного размера).

8) Комплексные сообщения, например. те, которые содержат ссылки на другие объекты, могут вызвать ужасающие проблемы с владением и пожизненным управлением, если они передаются по значению. Пример. Объект сокета сервера имеет ссылку на объект списка буфера, содержащий массив буферов-экземпляров разного размера (реальный пример с сервера IOCP). Попробуйте передать это значение.

9) Многие вызовы ОС не могут обрабатывать ничего, кроме указателя. Вы не можете PostMessage (это Windows API, для всех вас счастливы), даже 256-байтовая структура по стоимости с одним вызовом (у вас есть только 2 wParam, lParam целые числа). Вызовы, которые настраивают асинхронные обратные вызовы, часто позволяют передавать «контекстные данные» на обратный вызов - почти всегда только один указатель.Любое приложение, которое собирается использовать такую ​​функциональность ОС, почти вынуждено прибегать к использованию по ссылке.

0

Комментарий Джереми Фризнера кажется лучшим, поскольку это новая область, хотя точки Мартина Джеймса также хороши. Я знаю, что Microsoft изучает передачу сообщений для своих будущих ядер, поскольку мы получаем больше ядер.

Существует, кажется, структура, которая имеет дело с передачей сообщений, и утверждает, что она имеет гораздо лучшую производительность, чем текущие .Net-производители/потребительские дженерики. Я не знаю, как это будет сравнить с DataFlow .Net в 4,5

https://github.com/odeheurles/Disruptor-net