Насколько велика слишком велика для статического распределения пространства - PullRequest
2 голосов
/ 19 сентября 2011

Поскольку я не смог найти выход, используя данные, специфичные для потока, для дескриптора сокета, как показано в этом вопросе Вопрос об общей библиотеке и данных, специфичных для потока , я планирую объявить глобальный массив всего процесса с каждая строка имеет два элемента pthread_t и int (для socketfd). Таким образом, всякий раз, когда поток должен связаться с сервером, он ищет массив для своего сокета fd, используя свою идентификацию (pthread_self ()), и использует его для связи.

Но мне было интересно, вместо того, чтобы динамически выделять и освобождать пространство для этой структуры всякий раз, когда есть установка соединения или отключение соответственно, если у меня есть массив с размером, скажем 1000 ... он слишком большой / неэффективный (я буду надо искать тоже)? 1000 потоков не будет существовать одновременно. поэтому массив не всегда будет заполнен.

Спасибо

Ответы [ 4 ]

3 голосов
/ 19 сентября 2011

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

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

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

2 голосов
/ 19 сентября 2011

Во-первых, память, необходимая для 1000 элементов, умноженная на пространство для pthread_t и int, незначительна, если только вы не находитесь на встроенном компьютере или другой аналогично ограниченной системе.

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

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

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

1 голос
/ 19 сентября 2011

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

Сказав это, я считаю, что эти издержки будут незначительными по сравнению со стоимостью установки соединения. Но не верь мне, верь своему профайлеру

1 голос
/ 19 сентября 2011

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

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

Если у вас нет ограничений памяти, нет необходимости использовать malloc ().Подход к массиву аккуратен и удобен для исполнения.

HTH

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