Организация ввода в движке: два потока или один поток?

Тема в разделе "Машинное отделение", создана пользователем варяг, 26 окт 2006.

  1. варяг
    Оффлайн

    варяг Учаcтник

    Репутация:
    0
    Я честно признаюсь раньше с потоками дело не имел, потому и спрашиваю. У меня в программе сейчас 2 потока. Один для ввода (принимает команды от пользователя), во втором потоке должен крутиться движок. Никак не могу настроить потоки так, чтобы быстродействие было бы сопоставимо с однопотоковым приложением. Скорость падает в 2 раза. Это так и должно быть? Пробовал регулировать приоритетами SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL) - пока не помогает. Если задать потоку ввода приоритет THREAD_PRIORITY_BELOW_NORMAL - поток глохнет, ввести ничего нельзя. Когда у обоих потоков приоритет THREAD_PRIORITY_NORMAL все работает, но в 2 раза медленнее. Порылся в MSDN, но кажется испробовал уже все :(
     
  2. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    Моё мнение - один поток значительно лучше.
     
  3. WinPooh
    Оффлайн

    WinPooh В.М. Команда форума

    Репутация:
    95
    Я надеюсь, что у Вас поток, ожидающий ввод, делает это по таймеру, через определённое время?
    А в остальное время вызывает Sleep() или какой-то его аналог?

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

    Хотя и тут возможны разные пакости связанные с размером кванта времени в планировщике.

    Наверное, NS прав - одним потоком проще...
     
  4. варяг
    Оффлайн

    варяг Учаcтник

    Репутация:
    0
    Верно, в остальное время вызывает Sleep(), но и это не помогает. Наверное одним потоком действительно проще. Я уже как-то пытался одним потоком все организовать, но, как сейчас помню, были проблемы с организацией Pondering. Здесь какие-нибудь идеи будут?
     
  5. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    Проверяешь в Search наличие комманды от движка.
    Например один раз в 500 мс. Можно чаще.
    t:=timeGettime;
    if (t-poslT)>=500 Then
    Begin
    poslT:=t;
    // проверяем наличие инфы от движка
    // я делаю это при помощи winAPI - PeekNamedPipe() и т.д.
    end;

    А можно это всё перенести в отдельную ветку?
     
  6. WildCat
    Оффлайн

    WildCat Коршунов Игорь Команда форума

    Репутация:
    0
    У меня один поток.
    Как ожидать команд пока нет перебора понятно.
    Если идет перебор, то примерно 10 раз в секунду проверяется наличие команды на вводе:
    Код:
    int IsInputAvailable()
    {
      static int init = 0, pipe;
      static HANDLE inh;
      DWORD dw;
    
      if (!Inter) return 0; // если установлен флаг работать без прерываний
      if (!init) {
        init = 1;
        inh = GetStdHandle(STD_INPUT_HANDLE);
        pipe = !GetConsoleMode(inh, &dw);
        if (!pipe) {
          SetConsoleMode(inh, dw & ~(ENABLE_WINDOW_INPUT));
          FlushConsoleInputBuffer(inh);
          FlushConsoleInputBuffer(inh);
        }
      }
      if(pipe) {
        if(!PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL)) return 1;
        return dw;
      } else {
        GetNumberOfConsoleInputEvents(inh, &dw);
        return dw <= 1 ? 0 : dw;
      }
    }
    Этот код из Крафти. Более менее работает.
    Далее читаю команду в буфер, и смотрю возможна ли обработка не прерывая вычислений. Если нет, то устанавливаю флаг для окончания перебора. Далее работает обычный код обработки команд. Он первым делом смотрит, есть ли команда в буфере, и только затем берет новую команду со стандартного ввода.
     
  7. WildCat
    Оффлайн

    WildCat Коршунов Игорь Команда форума

    Репутация:
    0
    Мне очень трудно понять как может скорость падать в два раза. Ведь поток для ввода практически все время ожидает ввода, т.е. ничего не делает. Ему даже слипы не нужны.
    Покажи код потока ввода. Очень интересно, что ты там натворил.
     
  8. варяг
    Оффлайн

    варяг Учаcтник

    Репутация:
    0
    Все, эта тема умерла. Еще вчера я сделал все в одном потоке, прекрасно работает