Хобрук: Ваш путь к мастерству в программировании

Синхронизация циклических потоков

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

        // at end of loop on each thread...
        sig_thread_done();

        while (!is_sync_done())
        {
            PauseExecution(1);
        }

sig_thread_done и is_sync_done являются функциональными объектами из другого класса, который управляет списком всех «потоков». Эти функции выглядят так:

bool Core::IsFrameDone()
{
    MutexLock lock(manager_mutex);

    if (waiting_components == -1)
    {
        waiting_components = 0;
        return true;
    }
    return false;
}

void Core::SignalFrameDone()
{
    MutexLock lock(manager_mutex);

    if (++waiting_components == (int)components.size()) // components == threads
    {
        //sync shared data...
        waiting_components = -1; // -1 signifies that all threads have completed their iteration
    }
}

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

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

Я ценю любые идеи или предложения, которые кто-либо может предложить.

Ссылка на статью.


  • предложить вам ссылку на статью, на которую вы ссылаетесь. 22.01.2012
  • Концептуально вы пытаетесь реализовать барьер, так почему бы вместо этого не использовать проверенную реализацию, например. pthread_barrier? 22.01.2012
  • @АлексейКуканов Спасибо. Я посмотрю на это. 22.01.2012

Ответы:


1

Я думаю, вы пытаетесь заново изобрести барьер потоков.

22.01.2012
  • Кажется, так говорят все остальные. Я никогда раньше не слышал о нитевидном барьере, полагаю, мне следовало больше прочитать, прежде чем начинать этот проект. Спасибо за комментарий. 23.01.2012

  • 2

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

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

    22.01.2012
  • Спасибо. До того, как я попробовал это, все потоки выполнялись асинхронно и при необходимости использовали мьютексы. Это устранит накладные расходы на всю эту спорадическую синхронизацию. 23.01.2012
  • Новые материалы

    Понимание СТРУКТУРЫ ДАННЫХ И АЛГОРИТМА.
    Что такое структуры данных и алгоритмы? Термин «структура данных» используется для описания того, как данные хранятся, а алгоритм используется для описания того, как данные сжимаются. И данные, и..

    Как интегрировать модель машинного обучения на ios с помощью CoreMl
    С выпуском новых функций, таких как CoreML, которые упростили преобразование модели машинного обучения в модель coreML. Доступная модель машинного обучения, которую можно преобразовать в модель..

    Создание успешной организации по науке о данных
    "Рабочие часы" Создание успешной организации по науке о данных Как создать эффективную группу по анализу данных! Введение Это обзорная статья о том, как создать эффективную группу по..

    Технологии и проблемы будущей работы
    Изучение преимуществ и недостатков технологий в образовании В быстро меняющемся мире технологии являются решающим фактором в формировании будущего работы. Многие отрасли уже были..

    Игорь Минар из Google приедет на #ReactiveConf2017
    Мы рады сообщить еще одну замечательную новость: один из самых востребованных спикеров приезжает в Братиславу на ReactiveConf 2017 ! Возможно, нет двух других кланов разработчиков с более..

    Я собираюсь научить вас Python шаг за шагом
    Привет, уважаемый энтузиаст Python! 👋 Готовы погрузиться в мир Python? Сегодня я приготовил для вас кое-что интересное, что сделает ваше путешествие более приятным, чем шарик мороженого в..

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