Наверху из-за использования Событий

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

, Если I’m, работающий в команде, что уже как хороший фон на разработке веб-форм разрабатывают it’s намного легче представить MVP, чем MVC. Я сказал бы, что MVP в этом сценарии является быстрой победой.

Мой опыт говорит мне, что перемещение команды от веб-форм до MVP и затем от MVP к MVC относительно легко; перемещение от веб-форм до MVC является более трудным.

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

http://www.qsoft.be/post/Building-the-MVP-StoreFront-Gutthrie-style.aspx

6
задан Wookai 20 August 2009 в 14:12
поделиться

8 ответов

Если вы просто распараллеливаете циклы и используете vs 2008, я бы посоветовал взглянуть на OpenMP. Если вы используете Visual Studio 2010 beta 1, я бы посоветовал взглянуть на библиотеку параллельных шаблонов , особенно на «параллель для» / «параллель для каждого» apis или класс "группа задач , потому что они, вероятно, будут делать то, что вы пытаетесь сделать, только с меньшим количеством кода.

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

I 'Я предлагаю посмотреть на это в профилировщике, например xperf , профилировщике f1 в Visual Studio 2010 beta 1 (в нем есть 2 новых режима параллелизма, которые помогают увидеть конкуренцию) или Intel vtune.

Вы также можете поделиться кодом что вы выполняете задачи, чтобы люди могли лучше понять, что вы делаете, потому что ответ, который я всегда получаю по поводу проблем с производительностью, - это, во-первых, «это зависит от обстоятельств», а во-вторых, «профилировали ли вы это?»

Удачи

- Рик

"

Удачи

- Рик

"

Удачи

- Рик

1
ответ дан 8 December 2019 в 18:39
поделиться

На мой взгляд, это модель потребителя производителя,

3
ответ дан 8 December 2019 в 18:39
поделиться

Да, WaitForMultipleObjects довольно дорого обходится. Если ваши задания небольшие, накладные расходы на синхронизацию начнут превосходить затраты на фактическое выполнение работы, как вы видите.

Один из способов исправить это - объединить несколько заданий в одно: если вы получите «маленькое» задание (как бы вы ни оценивали такие вещи), храните его где-нибудь, пока у вас не будет достаточно мелких работ, чтобы сделать одну работу разумного размера. Затем отправьте их все в рабочий поток для обработки.

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

3
ответ дан 8 December 2019 в 18:39
поделиться

Остерегайтесь, вы все еще запрашиваете следующее задание после того, как издается endSignal.

for( ;; ) {
    // wait for one of the signals
    waitResult = WaitForMultipleObjects(2, signals, false, INFINITE);
    if( waitResult - WAIT_OBJECT_0 != 0 )
        return;
    //....
}
2
ответ дан 8 December 2019 в 18:39
поделиться

Это не должно быть так дорого, но если ваша работа практически не требует времени, то накладные расходы потоков и объектов синхронизации станут значительными. Подобные пулы потоков работают намного лучше для задач с более длительной обработкой или для тех, которые используют много операций ввода-вывода вместо ресурсов ЦП. Если вы ограничены процессором при обработке задания, убедитесь, что у вас есть только 1 поток на процессор.

Могут возникнуть другие проблемы, как getNextJob получает данные для обработки? Если копируется большой объем данных, то вы снова значительно увеличиваете накладные расходы.

Я бы оптимизировал его, позволив каждому потоку продолжать вытягивать задания из очереди, пока она не станет пустой. Таким образом, вы можете передать сотню заданий в пул потоков, и объекты синхронизации будут использоваться только один раз для запуска потока. Я'

1
ответ дан 8 December 2019 в 18:39
поделиться

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

Кстати, в чем конкретно ваш вопрос? Я смогу ответить более точно, задав более точный вопрос :)

РЕДАКТИРОВАТЬ:

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

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

РЕДАКТИРОВАТЬ: После дополнительных подсказок ...

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

Предположим, у вас есть 4 ядра и 10000 циклов для вычислений, как в вашем примере (в комментарии) . Вы сказали, что вам нужно дождаться завершения 4 потоков, прежде чем продолжить. Тогда вы сможете упростить процесс синхронизации. Вам просто нужно дать вашим четырем потокам th, nth + 1, nth + 2, nth + 3 цикла, дождаться завершения четырех потоков, а затем продолжить. Вы должны использовать рандеву или барьер (механизм синхронизации, ожидающий завершения n потоков). Boost имеет такой механизм. Вы можете посмотреть реализацию Windows на предмет эффективности. Ваш пул потоков не совсем подходит для этой задачи. Поиск доступного потока в критическом разделе - это то, что убивает ваше процессорное время.

1
ответ дан 8 December 2019 в 18:39
поделиться

Похоже, что все это событие (вместе с синхронизацией между потоками с использованием критических разделы) довольно дорого!

«Дорого» - термин относительный. Самолеты дорогие? Машины? или велосипеды ... туфли ...?

В этом случае возникает вопрос: являются ли события «дорогими» по сравнению со временем, которое требуется для выполнения JobFunction? Было бы полезно опубликовать некоторые абсолютные цифры: сколько времени занимает процесс, когда он «не связан»? Это месяцы или несколько фемтосекунд?

Что происходит со временем, когда вы увеличиваете размер катушки с резьбой? Попробуйте выбрать размер пула 1, затем 2, затем 4 и т. Д.

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

Выбор фигуры из воздуха (ничего не зная о вашей целевой системе и предполагая, что вы ничего не делаете '' огромный 'в коде, который вы не показали), я бы ожидал, что «накладные расходы на события» каждого «задания» будут измеряться микросекундами. Может, сотню или около того. Если время, затрачиваемое на выполнение алгоритма в JobFunction, не намного БОЛЬШЕ, чем это время, ваши потоки, скорее всего, будут стоить вам времени, а не сэкономить его.

1
ответ дан 8 December 2019 в 18:39
поделиться

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

С другой стороны, если время обработки 2500 итераций цикла больше, чем 100 микросекунд (на текущих ПК), возможно, вы столкнулись с ограничениями оборудования. Если ваша обработка использует большую полосу пропускания памяти, разделение ее на четыре процессора не даст вам большей пропускной способности, это фактически даст вам меньше из-за конфликтов. Вы также можете столкнуться с проблемами зацикливания кеша, когда каждая из ваших 1000 итераций будет очищать и перезагружать кеш 4 ядер. Тогда нет единого решения, а в зависимости от вашего целевого оборудования может и не быть.

1
ответ дан 8 December 2019 в 18:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: