С++ многопоточная оптимизация

в моем коде у меня есть 2/4 потока, выполняющие моделирование Монте-Карло. Каждый из них проводит ряд экспериментов, и все они собирают результаты в вектор stl. У меня такой вопрос: предположим, что каждый поток последовательно запускает 1000 экспериментов. Лучше ли сохранять результат в общий вектор по одному или время от времени? Если они будут ждать, пока у них будет какой-то согласованный объем данных, запись в вектор займет больше времени, поэтому я не уверен, обязательно ли второе решение лучше первого.

PS каждый эксперимент представляет собой численное вычисление, поэтому никаких операций ввода-вывода.

Спасибо


person Bob    schedule 19.01.2011    source источник
comment
У вас может быть общий стек без блокировок, и вы можете помещать в него результаты.   -  person GManNickG    schedule 19.01.2011


Ответы (3)


Если вы собираетесь ждать, пока все результаты будут вычислены, прежде чем использовать какой-либо из результатов, предварительно выделите место для 4000 результатов в векторе и заставьте каждый поток записывать в один диапазон элементов в векторе. Блокировка не требуется, поскольку никакие два потока не обращаются к одному и тому же элементу вектора.

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

person James McNellis    schedule 19.01.2011

Если вы помещаете в вектор только от 2000 до 4000 элементов, я сомневаюсь, что в любом случае это будет иметь большое значение.

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

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

person Michael Burr    schedule 19.01.2011

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

Если есть только один поток для чтения и один поток для записи в fifo... вам не нужна синхронизация. Хитрость заключается в том, чтобы в списке всегда оставался хотя бы один «фиктивный» элемент, а fifo пуст, если head == tail . Указателями головы и хвоста можно манипулировать для нажатия и выталкивания, так что нет необходимости в синхронизации.

Используя это .. вы можете сделать несколько вопросов .. которые не будут нуждаться в какой-либо синхронизации. Если создание/удаление требует времени .. вы можете иметь вопросы для хранения повторно используемых элементов.

удачи .

помните.. Ровно один читатель, и Ровно один писатель.. не больше, не меньше. Хитрость заключается в том, чтобы создать МНОГО таких Q, Q также для повторного использования объектов ... и вам не понадобятся какие-либо вещи для синхронизации потоков ...

Если ваши Q действительно пусты ... просто необходима функциональность sleep () / wakeup ().

и если я еще не сказал... Ровно один читатель и Ровно один писатель.

person vrdhn    schedule 19.01.2011
comment
Доступ к указателям по-прежнему необходимо синхронизировать либо с помощью блокировки, либо атомарной. Связанный список может снизить производительность; связанные списки для большинства случаев использования чрезвычайно неэффективны по сравнению с другими контейнерами последовательностей (конечно, существенна ли стоимость производительности, полностью зависит от варианта использования OP). - person James McNellis; 19.01.2011
comment
@James .. нет .. доступ к указателю НЕ нужно синхронизировать .. в этом красота .. думайте концептуально .. если есть длинный односвязный список .. оба потока когда-либо изменят одну и ту же ячейку памяти! - person vrdhn; 19.01.2011
comment
Даже если только один поток изменяет указатель, а другой поток просто читает его, доступ к нему должен быть синхронизирован. Это всегда возможно и весьма вероятно в головном и хвостовом узлах, если связанный список используется в качестве очереди. - person James McNellis; 19.01.2011
comment
@James, пожалуйста, напишите код .. ни в одной ячейке памяти не будет одновременного RW или WW ... - person vrdhn; 19.01.2011
comment
Собственно, теперь я в замешательстве. Вы предлагаете использовать связанный список в качестве очереди, но только один поток будет изменять список. Как элементы должны быть удалены из очереди? Возможно, вы сможете продемонстрировать то, что пытаетесь объяснить. - person James McNellis; 19.01.2011
comment
Это не объясняет, как элементы удаляются. Добавляет ли один поток элементы в очередь (используя push_back), а другой поток удаляет элементы из очереди (используя pop_front)? - person James McNellis; 19.01.2011