Подскажите, можно ли повысить производительность алгоритма за счет распараллеливания потоков? Согласно теории "Эффективность приложения повышается при создании внутри него нескольких потоков, одновременно решающих независимые друг от друга задачи." У меня есть функция, в которой производится длительные сложные итерационные вычисления. Исходные данные для расчета, например, числа Х,Y,Z. Я сейчас выделяю отдельный поток, в котором последовательно на вход вычислительной функции подаются эти числа. Одно из них является решением задачи. Есть нормальное желание разделить этот поток на 3 потока, в котором каждый поток, как бы по отдельности, работал с числами Х,Y,Z. Но меня смущает то, что на самом деле, распараллеливание потоков является виртуальным, как бы идет псевдопаралельное выполнение. Ведь потоки на самом деле выполняются не одновременно, а по очереди, но переключение между ними происходит так часто, что кажется будто они выполняются параллельно. Тогда есть ли большая разница между выполнением кода в одном потоке или в трех? Каково Ваше мнение?
Есть разница. В твоем случае код в трех потоках будет работать в несколько раз медленее. Всегда следуй правилу - в случае отсутсвия в приложении блокирующих операций, число потоков должно быть равно числу процессоров. Если блокирующие операции имеются, то оптимальное число потоков подбирается экспериментально.
Сейчас в современном процессоре по-настоящему уже несколько ядер. Так что лучше писать с потоками - будет быстрее работать на современных машинах.
Вот выдержка из статьи - "Поэтому следующим шагом развития является увеличение количества ядер - практически, нескольких процессоров в одном корпусе". Если ты это имел ввиду - то у меня, к сожалению, только один процессор.
в современном мире параллелизм должен быть везде. начиная от обычного последовательного исполнения кода (параллелизм по данным) и заканчивая параллельно выполняемым кодом (разными потоками и/или разными ядрами/процессорами). Code (Text): // a = b + c + d + e // преобразуется в следующее f = b + c g = d + e a = f + g
А еще надо читать название топега прежде чем постить ответы. Кажется там ясно написано , и аффтар знал о чем именно он спрашивает. Странно, но многие участники форума не удтруждают себя чтением названий топиков и вопросов аффтора, а сразу переходят к ответам.
Я как раз и прочитал название топика. Могу еще раз повторить, для особо непонятливых - один процессор (в топике "однопроцессорном"), в настоящее время это больше чем одно ядро (Pentium 4+HT, Pentium D, Core2Duo). Извините за оффтоп.
Ultrin Faern Не прикапывайся к словам. Аффтар имел в виду именно одно ядро, так как многоядерный процессор равнозначен мультипроцессорной системе (и программно выглядит в точности как мультипроцессорная система).
точнее бы написть один логически процессор, тогда бы точно непоняток не было =) а по теме - это смотря где работаешь - в rtos да, разницы будет мало. А вот в винде планировщик будет выделять твоему процессу больше времени, и следовательно программа быстрее просчитает.
Больше времени уйдет на само переключение потоков. Быстрее может посчитать только в том случае, если в системе еще есть чужие потоки которые выполняют активные вычисления, но в этом случае правильным решением будет повышение приоритета потока.
Спасибо за высказанные мнения. По-видимому, я все же не точно сформулировал вопрос, так как возникли разночтения. В моем понимании было процессор и ядро - одно и то же. Наверное, надо было сразу написать, что у меня - АMD Athlon(tm) 64 Processor 3200+ и ничего подобного типа Pentium 4+HT, Pentium D, Core2Duo нет. Работаю на WinXP. И судя по тому, что написали в теме - мне не удасться ускорить вычислительную работу алгоритма за счет распараллеливания потоков.
asmfan: Ага, а теперь представь, что у юзера запущено десяток приложений, и каждое, как и твое, без особой на то необходимости создает несколько тредов Не спорю, когда нибудь и будут 128-ядерные процессоры, но пока даже не предвидится. Так что не стоит фигней страдать, проще приоритет повысить.
AndNot Можно вообще вернуться в DOS (не в смысле отказа обслуживания) - операционную систему, где всё время процессора отдавалось одной задаче. Просто кто не пишет и не собирается писать многопоточные программы - в будущем делать нечего (да и в настоящем тоже). Как пример рассмотрим программку с окном, рассчитывающую большой факториал. Есть как минимум 2 способа сделать это: 1) сделать это в оконной ф-ии - как следствие "повисание" GUI программы. 2) сделать это через потоки - "сложность" реализации. Я выбираю 2е. Не буду сейчас вдаваться в подробное описание OoOE (out-of-order execution), что уже в себе подразумевает параллелизм исполнения. В общем, пора выбираться из ДОСа.
asmfan Для этого есть стандартные решения типа ProgressBar и т.п. ОоО как раз предполагает оптимизацию однопоточного приложения, грубо говоря разбивку его на независимые "микропотоки" инструкций, выполняющиеся "параллельно" (с перекрытием во времени). Твой же пример с разбивкой a = b+c+d+e на два независмых сложения за счет ОоО даст выигрыш (особенно на FPU) и без всякой разбивки на классические виндовые потоки
leo Об этом я и говорил в 1м своём посте, говоря о "начиная от обычного последовательного исполнения кода (параллелизм по данным)". И всё же я считаю, что ПО научится пользоаваться данными процессора по оптимизации самого же себя в рантайме - число ядер; число потоков, исполняющихся параллельно на одном ядре; ширина кэш-линии; размер кэша и т.п. Рантайм идентификация особенностей архитектуры и набора расширений процессора сделают своё дело по формированию эффективной обработки данных - разбивки на потоки, на р-ры данных для кэша на специальные инструкции данного семейства и проч. Для всего это лишь надо пользовать cpuid корректно и всё... вуаля.
asmfan НТ скоро канет в лету вместе с P4, и видимо раньше, чем ты научишься оптимально использовать эту фичу А о других технологиях исполнения потоков "параллельно на одном ядре" я вроде ничего не слышал На правах рекламы ? К сожалению мало знать фичи процессора, нужно еще и уметь их использовать. Это во-первых. А во-вторых, для критических задач проще задавать требования к процессору или сразу при оптимизации ориентироваться на некоторый круг процессоров\параметров, чем писать код в "десяти вариантах" под каждый камень
Не нужно крайностей, все хорошо вмеру. Просто не стоит забывать про нехилые издержки на переключение потоков. К тому же, в большинстве случаев, любое переключение задач очень больно бьет по кэшу. Не случайно над этой проблемой сейчас усиленно работают. Ты путаешь совершенно разные понятия. Распаралеливание инструкций - это совсем не тоже что многопоточность. К тому же, чем меньше прерывают некий поток, тем эффективнее он сможет использовать распаралеливание. Зачем же старых друзей бросать Может и пригодится еще ;-? Когда шампанское готовить?