| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > параленые вычисления |
| Автор: box 14.11.2013, 16:46 |
| всем привет! есть один процесс , занимает одно ядро. там есть возможность заполнить данными некий массив или контейнер или участок шеред памяти , но проблемма в том что данные заполняются слишком быстро (скорость доставки данных в юзер спейс состовляет 65 тактов процессора и можно выбирать данные. ) вот кто нибуть знает способ расспаралелить выборку данных желательно без блокировок ато одно ядро явно не справляется тобиш лучше будет сделать так : если одно ядро загруженно на 70% то мы подключаемся к вычислениям другим ядром и так далее до исчерпания ресурсов процессора интересует механизм реализации |
| Автор: bsa 14.11.2013, 17:15 |
| есть понятие lockfree. поищи. Но, если честно, я не очень понял, где у тебя затык. долгая работа с контейнером или ядром? |
| Автор: box 14.11.2013, 17:31 |
| затыки на такой скорости везде , сплош и рядом , например я провел експеремент и выяснил что максимальная скорость заполнения контейнера типа unordered_map данными типа char[16] сгенерированные случайным образом состовляет всего 500к еллементов в сек а это очень мало , это дуал ксеоне 2.4 ггц ддр3 1333 мгц , это при использовании одного ядра и без блокировок , с блокировкой если юзать 2 или более ядра конечная цыфра состовляет 300к елементов в сек , значит выходит ято мютекс не так эфективен как хотелось бы , но даже если заполнять контейнер со скоростью 500к елементов в сек то этого все равно мало |
| Автор: bsa 14.11.2013, 17:47 |
| box, какая-то странная у тебя программа. Обычно, в подобных случаях используют простые контейнеры (типа vector, deque или вообще кольцевые). Т.е. time critical код пишет исключительно в простой контейнер. А уже обработка ведется несколькими потоками асинхронно извлекающими данные из него. Не уверен, что есть возможность без блокировок писать в unordered_map из двух потоков одновременно. Контейнер такой... |
| Автор: box 14.11.2013, 17:52 |
| так вектор тоже вроде требует мютекс при ассинхронном доступе на запись |
| Автор: azesmcar 14.11.2013, 18:42 |
| количество данных заранее неизвестно? есть конкретные требования к структуре данных? есть требования к очередности заполнения? можно скажем заполнить два отдельных контейнера а потом соединить? если нужно эффективно, то надо писать свой контейнер, а не выставлять lock на стандартном. используя стандартный контейнер ты лишаешься возможности вынести за пределы lock-а то, что можно сделать параллельно и ты привязываешь всю работу с контейнером к одному единственному мьютексу, что тоже лишает тебя возможности распределить нагрузку. |
| Автор: box 14.11.2013, 19:51 |
| данные летят постоянно с сетевого интерфейса и попадают в юзерспейс за 65 тактов процессора , там даже данные не копируются а указывается поинтер на участок шеред памяти (zero copy netmap bridge). структура данных это unsigned char |
| Автор: akizelokro 15.11.2013, 00:32 |
| Есть работа стандартная, а есть "ювелирка". И есть у меня такое глубокое мнение, что когда тебе критично выжимать 100% мощи, библиотека stl вообще отбрасывается в сторону и пишется штучная вещь. Под конкретные условия. Либо ищется подобная либа под задание. |
| Автор: bsa 15.11.2013, 10:02 |
| В вектор можно писать из миллиона потоков одновременно, если нет изменения размера массива. Т.е. делаешь массив достаточного размера и пишешь туда. Короче, как сказали выше задача у тебя не простая и решать ее нужно используя спец. техники. Рекомендую изучить соответствующие ресурсы.Я читал про кольцевые контейнеры используемые при подобных задачах. |
| Автор: akizelokro 15.11.2013, 15:31 |
| Делай набор контейнеров (или областей памяти). Основной поток заполняет их до определённого условия, после чего создаёт новый контейнер (область памяти), запускает для него поток разбора, который "бьёт" заполненный обьект (разбирает), уже не нуждаясь в блокировках для него, сам же поток переходит к заполнению следующего объекта. Но тут проблема такая, что ты не сказал ничего по постановке задачи. Вариантов алгоритмов можно придумать до чёртиков, но пока что ты ничего не сказал по разбору, каковы необходимые условия и так далее. А проблемы со скоростью решаются, исходя из элементарной логики, не программерской даже, так. Находишь узкое место (места) и "расширяешь" их. |
| Автор: box 15.11.2013, 18:09 |
| одно из условий это возможность очишать использованные данные с разрешением в одну секунду но главная проблема это как синхронизировать без блокировок данные перед отправкой в ядро и все равно мы упремся в скорость заполнения контейнера и время обработки данных |
| Автор: akizelokro 16.11.2013, 10:12 |
| Для начала попробуй раздробить задачу. Все контейнеры stl, да и любые контейнеры и объекты зависят от размера с точки зрения выполнения времени операции и выделения памяти. Одни больше, другие меньше, но для всех факт один. Что чем больше размер конейнера, тем ниже суммарная производительность по трём основным операциям (вставка + поиск + удаление). Отсюда прямо читается необходимость разбиения контейнера (объекта сообщений) на несколько (много), а указатели их закидывай в какой-то основной контейнер. Когда дробный контейнер заполнен и вставок в него больше не будет, ты будишь поток обработки, по завершению обработки переводишь его в спящее состояние. При завершении обработки поток удаляет этот дробный контейнер (если он достаточно велик), затем сновапереводится в спящее состояние. Потом же посмотри узкие места. Позволяет ли тип данный делать подобие буфферизации? (добавлять данные в конец уже внесённых) Каково наращение capasity контейнеров и надо ли его увеличить, чтобы при такой скорости не гонять методы увеличения ёмкости контейнера? Или пиши свой контейнер под свои нужды. Если тебе интересна и многоядерность, то тут, пожалуй, надо вспомнить,кто у нас дока. А дока здесь Intel. Если интересно, глянь что может предоставить tbb и их С++ компилятор. Смутное предположение, что несколько приятных сюрпризов они смогли заготовить. |
| Автор: akizelokro 16.11.2013, 11:43 |
| Грубо говоря, тут надо смотреть уже "теологически". В stl три основные операции (вставка/добавление + удаление + поиск). Операцию сортировки ты не рассматриваешь, раз используешь unsorted контейнер. Также контейнеры, скажу, организованы, чтобы не сказать "оптимизированы" и для применения обобщенных алгоритмов, которых тебе тоже, как я понял, не надо. Здесь у тебя остаётся один ключевой момент - операция поиска. Так вот, если поиск по всем сообщениям тебе не нужен, ты отказываешься от использования одного общего контейнера. Потому что за любое ограничение/удобство/дополнительную функцию тебе приходится платить производительностью. |
| Автор: box 16.11.2013, 13:36 |
| заполнить контейнер это пол беды , а вот как слать сигналы из воркеров в основной процесс на таких скоростях , сигналы типа разрешить/запретить пакет . я вот думаю может лучше вместо контейнеров юзать сокеты ? |
| Автор: akizelokro 16.11.2013, 14:15 |
| да хоть что применяй, что тебе подходит. но я так понимаю, что основной поток тебе нужно разгрузить. у тебя, как я понял, встала задача реорганизовать логику. Если тебе удастся разгрузить и разделить данные и потоки(процессы) по их обработке, то ты получишь нехилый выигрыш в поизводительности. Если есть возможность разделить пакеты по какому-то признаку, что обработчики пакетов не будут пересекаться и группы пакетов можно будет обрабатывать независимо друг от друга, это совсем другой табак. |
| Автор: Pavia 16.11.2013, 16:02 |
| box, Всё очень просто вам надо нанять программиста или студента он вам всё сделает. |
| Автор: akizelokro 18.11.2013, 03:28 |
| Студента? Мило! Программиста? У меня сейчас разгон простой, полгода в Сочах потрепыхаться, потом в Нью-Йорку. |
| Автор: ТарасАтавин 23.11.2013, 14:26 |
| box, если проблема в том, что даже одно ядро работает слишком быстро, то второе не поможет, нужен делей. |