ветвление против многопоточности - PullRequest
0 голосов
/ 14 марта 2011

В коде есть быстрый путь, который выглядит следующим образом:

while(1){

   select(fd_set...);

   if (fd_isUserspace) {
       process_user_packet(fd);    // RPC involved
   } else { // kernel 
       process_kernel_packet(fd);  // RPC invovled
   }
} // while(1)

По сути, чтение активного fd из набора fds и его обработка.В настоящее время это делается в ветви if-else и возвращается только после завершения обработки.Я думаю, что я могу улучшить это, используя пул потоков (poolSize> = 2) внутри if-else, чтобы обработка func немедленно возвращалась и могла снова начать цикл while для будущих fds.

Предположительно, пакет процесса _ * _ выполнит некоторую работу RPC для обработки.

Я знаю, что отправка задания обработки в поток может иметь некоторые издержки (thread_cond_signal / блокировка и т. Д.),но чувствую, что поскольку процесс _ * _ пакет, вероятно, занимает больше времени (из-за RPC), может быть, это того стоит.

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

-Спасибо

Ответы [ 2 ]

2 голосов
/ 14 марта 2011

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

Одно огромное преимущество, если вы используете несколько потоков: у вас больше нет запросов на блокировку. Вы получите лучшее время отклика, потому что сможете обрабатывать несколько запросов одновременно.

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

С некоторым пулом потоков, вы бы просто сделали:

while(1){

   select(fd_set...);

   if (fd_isUserspace) {
       submit_job(process_user_packet, fd);
   } else { // kernel 
       submit_job(process_kernel_packet, fd);
   }
} // while(1)

Где мы предполагаем, что submit_job имеет подпись

 void submit_job(void (*func)(void *), void *args);

Так что каждый поток в пуле потоков может просто получить функцию и аргументы, с которыми он должен работать, и вызвать func (args);

Я бы не стал беспокоиться о стоимости отправки работы. Если обработка занимает больше 1 миллисекунды (возможно, даже в действительно хороших реализациях), тогда вы будете великолепны.

1 голос
/ 14 марта 2011

Просто идея, но что, если вместо этого вы выбрасываете select и просто используете один поток на дескриптор файла?Единственный серьезный недостаток - это издержки переключения контекста, если слишком много запросов отображаются одновременно, но это может быть предпочтительнее задержки в любом случае.Преимущество заключается в меньшем количестве переключений контекста в не перегруженном случае: ядро ​​напрямую пробуждает поток, ожидающий файловый дескриптор, как только он разблокирован, а не сначала пробуждает поток выбора, который должен затем активизировать поток для обработки запроса,И, конечно же, простота чего-то преимущества сама по себе ...

...