На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (6) 1 [2] 3 4 ... Последняя » все  ( Перейти к последнему сообщению )  
> Распараллеливание выполнения без блокировок

    offsop was censored
    Цитата Wound @
    Ну ты ж отцов то читать не хочешь. Мне тебе сюда всю книгу цитировать или как?

    Да нет, я желаю на каждый "профессиональный взгляд" иметь кроме бла-бла-бла - что-то подтверждающее. Ну напиши мне строку в моем коде, обоснуй ошибку. Так уже третья моя просьба мимо. Спрашивается, а нахрена твои слова, если по существу не можешь указать где плохо и как лучше? Извини за эмоции.

    Цитата Wound @
    С блокировками оно надежнее, особенно когда у тебя есть расшаренный ресурс

    Бинго! Вот этого ДЖВА года ждал! :lol: А еще надежнее - записывать параллельно в бумажный журнал.

    Цитата Wound @
    Сегодня у тебя один продьюсер и один потребитель. Завтра может быть несколько потребителей, а после завтра - появятся несколько продьюсеров и несколько потребителей.

    А ты почитай-почитай про lock-free структуры. Когда прочитаешь, прочитай еще раз. И только потом ты поймешь, что то, что я процитировал тебя выше - лютая дичь от незнания. Я читаю и учусь, и ты читай.
    Сообщение отредактировано: Qraizer -
      Цитата Wound @
      С блокировками оно надежнее

      Этот аргумент я себе запишу в смартфон!!! :lol: :lol: :lol: Это не должно умереть!

        offtop was censored
        Цитата JoeUser @
        Да нет, я желаю на каждый "профессиональный взгляд" иметь кроме бла-бла-бла - что-то подтверждающее. Ну напиши мне строку в моем коде, обоснуй ошибку. Так уже третья моя просьба мимо. Спрашивается, а нахрена твои слова, если по существу не можешь указать где плохо и как лучше? Извини за эмоции.

        Я тебе уже привел хренову тучу аргументов - отказаться от std::thread, тебе этого мало? Так а нахрена ты тут тему вообще создал? Комить уже, ёпта. Все там нормалёк, остальные косяки по мере поступления разрулишь.

        Цитата JoeUser @
        Бинго! Вот этого ДЖВА года ждал! А еще надежнее - записывать параллельно в бумажный журнал.

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

        Цитата JoeUser @
        А ты почитай-почитай про lock-free структуры. Когда прочитаешь, прочитай еще раз. И только потом ты поймешь, что то, что я процитировал тебя выше - лютая дичь от незнания. Я читаю и учусь, и ты читай.

        Ну конечно. Ты даже постом выше уже признал что std::cout у тебя не потокобезопасен.

        Цитата JoeUser @
        Этот аргумент я себе запишу в смартфон!!! Это не должно умереть!

        Конечно запиши, и желательно еще сделай обои на рабочий стол с этим текстом, чтоб не забыть.

        offtop was censored
        Сообщение отредактировано: Qraizer -
          Цитата JoeUser @
          Этот аргумент я себе запишу в смартфон!!! Это не должно умереть!

          А так оно и есть. С блокировками у тебя всегда есть части кода, гарантированно выполняющиеся одним потоком. Это банально проще отлаживать и куда быстрее писать, чем сидеть и представлять "а вот тут у меня будет переключение контекста, сюда вклинится другой поток и выполнит воон ту фигню" с lock-free. Так что да, решение с блокировками наверняка окажется надёжнее из-за своей простоты.
            offtop was censored

            Цитата Wound @
            Я тебе уже привел хренову тучу аргументов - отказаться от std::thread, тебе этого мало?

            Прости, я что-то кроме бла-бла-бла не заметил сути. Перечисли, пожалуйста (ПОЖАЛУЙСТА)!!! еще раз по пунктам. Чем тебе плох std::thread?

            Цитата Wound @
            потому что у тебя нет блокировок и гарантировать что эта операция потокобезопасная - нельзя

            Т.е как я тебя понимаю, если в Стандарте написано, что данная операция из текущей версии STL атомарная - тебе насрать?! Ты этому не доверяешь?

            Цитата Wound @
            Ты даже постом выше уже признал что std::cout у тебя не потокобезопасен.

            Не "даже" а "всего лишь" - ощути разницу! А ты из говно-момента делаешь себе корону. Хотя нет, мелочей нет. Ты тут прав. Это есть косяк и он должен быть запомнен на будущее.

            Цитата Wound @
            как Pavia, за то что не привел тебе пруфы

            А вот на зло тебе и ему не выдам! :lol: Он не просто ограничился "тезисом", а пытался обосновать. А ты, как всегда, с шашкой на-голо в бой. Нихрена не понял, но по ходу разберемся :lol: Киля, не парься - ты на форуме есть, и это клёво! Даже если мы стреляемся из разных барикад :)
            Сообщение отредактировано: Qraizer -
              Цитата OpenGL @
              А так оно и есть. С блокировками у тебя всегда есть части кода, гарантированно выполняющиеся одним потоком. Это банально проще отлаживать и куда быстрее писать, чем сидеть и представлять "а вот тут у меня будет переключение контекста, сюда вклинится другой поток и выполнит воон ту фигню" с lock-free. Так что да, решение с блокировками наверняка окажется надёжнее из-за своей простоты.

              А мне не надо "надежнее надежного". Мне надо чтобы инварианты из STL выполнялись. И если там есть часть функций/методов которые работают с lock-free структурами, я буду ими пользоваться. Нравится вам это или нет.

              Я вас спросил в первом посте - есть ошибки? А вы меня грузите опасениями!!! Мне этого не надо, я это не просил !!!
                Тут интересное по теме - Параллельное программирование на С++ в действии.Уильямс
                В том числе и по lock-free структурам.
                  Цитата JoeUser @
                  Мне надо чтобы инварианты из STL выполнялись.

                  Какие инварианты и как их нарушает решение с блокировкой?

                  Цитата JoeUser @
                  Я вас спросил в первом посте - есть ошибки?

                  Так я и не спорю. Хочешь делать нерационально - дело твоё, мне-то что?
                    Цитата OpenGL @
                    Какие инварианты и как их нарушает решение с блокировкой?

                    "Перпендикулярный" вопрос ващето! Я про атомарные операции библиотеки... Они и гарантируют инварианты.
                    "Решения с блокировкой" - это вами навязываемая шляпа, к которой я в данном треде никакого отношения не имею.

                    Цитата OpenGL @
                    Хочешь делать нерационально - дело твоё, мне-то что?

                    Вот пошла тема!!! Рациональность. Прекрасненько. Тут есть о чем поговорить. Расскажи мне, пожалуйста, как сделать рациональнее!
                    Вводная: есть GUI процесс, есть процесс, опрашивающий Кардридер в неблокирующем режиме.
                    В моем синтетическом примере основной процесс = ReaderThread, а процесс опроса Кардридера WriteThread.

                    Жду более "оптимальный" вариант и конечно же его обоснование!
                      Цитата JoeUser @
                      Я про атомарные операции библиотеки... Они и гарантируют инварианты.

                      Тогда ты просто сам не понял, что сказал, потому что в этом контексте фраза "чтобы инварианты из STL выполнялись." теряет смысл.

                      Цитата JoeUser @
                      Вводная: есть GUI процесс, есть процесс, опрашивающий Кардридер в неблокирующем режиме.

                      У тебя там lock-free контейнеры при межпроцессном взаимодействии? :D Мсье знает толк, однако. Чем тупое решение с блокировкой не устроило-то?

                      Добавлено
                      По-моему тут что-то из разряда "если в руках молоток, то всё кажется гвоздями"
                        Цитата OpenGL @
                        Тогда ты просто сам не понял, что сказал, потому что в этом контексте фраза "чтобы инварианты из STL выполнялись." теряет смысл.

                        :blink:

                        Не понял тебя. Атомарные операции гарантируют "единоличный" доступ/операции. Считывание, обмен... Ты о каком смысле вообще?

                        Цитата OpenGL @
                        Мсье знает толк, однако. Чем тупое решение с блокировкой не устроило-то?

                        Мусье, а вы бы мне могли обосновать необходимость блокировки, где и без нее можно обойтись?
                        И еще, мусье, вы немножко знакомы с тезисом Уильяма из Оккамы ("Бритва Оккамы"), и если "да",
                        спросите себя - нахрена городить огород? Я имею ввиду- блокировками, если и без них все
                        прекрасно?
                          Цитата JoeUser @
                          Не понял тебя. Атомарные операции гарантируют "единоличный" доступ/операции. Считывание, обмен... Ты о каком смысле вообще?

                          Ну перечитай ещё раз :-? Разжёвывать очевидную мысль, да ещё оффтопя, мне не интересно.

                          Цитата JoeUser @
                          Мусье, а вы бы мне могли обосновать необходимость блокировки, где и без нее можно обойтись?

                          Звучит примерно как "обоснуй необходимость компилятора, ведь можно в hex кодах всё написать". Можно, конечно, просто это сложно. lock free алгоритмы в разы более сложные в написании и отладке, да ещё и далеко не всегда они работают быстрее (по-моему очередь и стек так вообще часто медленней оказываются, чем с блокировкой), так что в данном случае всё наоборот - ты должен обосновать необходимость реализовывать с lock-free. У тебя есть замеры времени в реальных условиях, из которых следует, что ты много времени тратишь на на ожидания в мьютексах? Или может быть твоя основная цель это научиться работать с lock-free? Если ответа на оба вопроса "нет", то твоё решение менее рационально, чем решение с блокировками.
                          Сообщение отредактировано: OpenGL -
                            Цитата OpenGL @
                            Разжёвывать очевидную мысль, да ещё оффтопя, мне не интересно.

                            Я немного гиперболизирую, несколько в обход вежливому общению. Просто представь, ты пишешь утверждение типа:
                            censored.
                            M
                            Вы с OpenGL не поняли друг друга. Это не повод обижаться и раскультуриваться. Я понял каждого, хоть и не с первого раза. Вы оба правы, но говорите о разных предметных областях.


                            Цитата OpenGL @
                            Звучит примерно как "обоснуй необходимость компилятора, ведь можно в hex кодах всё написать".

                            Что мой FreeStack так серьезно сложен? Да ладно? Да ладно!
                            Есть другое мнение. Для компиляции Хэллоу Ворлда не нужно ставить lcc (в 624KB), а нужно ставить вcю студию в более чем 11GB. Зачем?
                            ДА НА ВСЯКИЙ СЛУЧАЙ !!! Прекрасная логика!

                            ПРЕСНАЯ ВОДА ПО ПРЕЖНЕМУ detected!
                            В первой теме код и вопросы. Это тема.
                            Сообщение отредактировано: Qraizer -
                              Цитата JoeUser @
                              Вводная: есть GUI процесс, есть процесс, опрашивающий Кардридер в неблокирующем режиме.
                              В моем синтетическом примере основной процесс = ReaderThread, а процесс опроса Кардридера WriteThread.

                              Жду более "оптимальный" вариант и конечно же его обоснование!

                              Не хотелось бы встревать в жёсткую дискуссию..что-то я устал
                              за последнее время.
                              Могу просто рассказать, как делал сам.
                              А в качестве обоснования могу привести наисерьёзнейший аргумент:
                              "Нутром чую, что правильно - именно так".
                              Скрытый текст

                              Итак, есть GUI - приложение с его оконной процедурой.
                              Есть рабочий поток (или потоки) которые что-то там много делают.
                              Пусть будет карт-ридер, это неважно. Хоть 10.

                              1. Смастерим класс-коммуникационный объект, для работы и обмена между
                              разными потоками. Это будет шаблонный класс.
                              Его основа - две потоко-безопасные очереди. Разного направления,
                              условно "туда и обратно". Где хочешь их бери, хоть сам луди.
                              (а что такое очередь? Это массив, индексы которого рассчитываются по алгоритму очереди)

                              2. Напишем класс-интерфейс для возбуждения событий.
                              Назовём его, например, I_RiseEvent. У него будет роутина RiseEvent, которая будет
                              реализовываться в дочерних классах.

                              3. Класс нашего главного окна (или любого другого, которого надо)
                              назначим наследником - того библиотечного класса окна и интерфейса I_RiseEvent.
                              Множественным наследованием.

                              4. Тоже самое с нашим рабочим потоком - он наследник базового класса - потока и I_RiseEvent.

                              5. Инициализация комм-объекта произойдёт после создания объекта рабочего потока и окна.
                              Дело в том, что объекту коммуникации надо обязательно передать указатели на объекты-интерфейсы
                              потока и окна. Идея тут простая - когда один из участников обмена засылает
                              структуру обмена в очередь, автоматически возбуждается событие на принимающей стороне.
                              А поскольку интерфейс - абстрактен, и реализация возбуждения события происходит
                              в конкретном объекте конкретного класса проекта, значит наш коммуникационный объект
                              от проекта вообще не зависит. Это прекрасно, и мы можем включить такой класс
                              в библиотеку и пользоваться проверенным решением во всех проектах.
                              Поскольку наш коммуникационный объект (и используемые им очереди) мы сделаем
                              шаблонным классом. А значит, пригодным для работы с любыми типами данных.

                              6. как всё работает - допустим юзер щёлкнул по кнопке - обработчик кнопки заполнил
                              структуру с запросом, занёс её в коммуникационный объект в направлении "туда".
                              Сам факт занесения вызвал процедуру "RiseEvent" у объекта-потока.
                              Эта процедура подожгла семафор.
                              Семафор разбудил поток, который мирно спал на Wait-процедуре.
                              Поток запустил обработчик работы/опроса чего надо. Допустим, карт-ридера.
                              Через некоторое время (а главному окну всё это пофигу) операция завершилась.
                              Как-то. Обработчик потока записал результаты в какую-то там (заранее изобретённую)
                              структуру и заслал в коммуникационный объект в очередь "обратно". Сам факт записи в очередь
                              вызвал процедуру "RisEvent" уже главного окна. Чтобы не работать в контексте
                              рабочего потока, окно пошлёт само себе асинхронное, заранее предусмотренное
                              сообщение.
                              Получив сообщение, обработчик окна этого сообщения извлечёт из очереди структуру
                              с результатом... и у юзера в строке статуса (например) появится сообщение -
                              "Операция такая-то завершилась успешно"


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

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

                              Привожу пример - получаем по сети данные и строим график.
                              1-й рабочий поток непосредственно работает с сетью, получает данные,
                              проверяет, преобразовывает, засылает в комм-объект, засыпает.
                              2-й рабочий поток-графопостроитель. Получает данные 1-го, просыпается,
                              начинает рисовать, результат засылает в комм-объект (другой уже) засыпает.
                              3-й поток - главного окна. Возбуждение события приведёт к извлечению картинки
                              и перерисовке ею главного окна.
                              Однако, графопостроитель - приёмник запросов не от одного комм-обекта.
                              Он должен получать данные от главного окна :
                              - при измерении размеров окна
                              - при изменении графических параметров - цветА, фонты, вид гафика, их количество итд.
                              Все, что можно назвать "формой представления".
                              И поток-графопостроитель действительно будет выполнять все эти запросы от 3-х источников
                              последовательно и слать результат одному приёмнику (в виде картинки главному потоку).

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

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

                              Как-то так.
                                Цитата JoeUser @
                                Что мой FreeStack так серьезно сложен? Да ладно? Да ладно!

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


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0596 ]   [ 17 queries used ]   [ Generated: 29.03.24, 13:35 GMT ]