Подумалось тут на досуге что чем Лучше сразу такую IDE а в ней всего одна кнопка "Бабло" нажал и счастлив
>каждый второй пытается убить сиплюсплюс.. А разве питон сиплюсплюс совсем убить пытается? Или всё же он пытается занять нишу, где цпп не так крут?
Vladson, ведь все к этому идет ИМХО различие между перфокартами, на которых делала дырочки моя бабушка и каким-нибудь PHP фреймворком. Почти такие же как между фреймворком и написанием программы на русском в свободной форме....
кстати, а в прородителе ооп - симуле, - объекты как раз были "процессами". в кавычках потому, как многопоточности тогда ещё не было и объекты просто передавали друг другу управление по очереди.
vasa_c, угу, пытается. то и дело появляются новости, как питон обогнал цпп на каком-нибудь синтетическом тесте, не требующем активной работы с памятью. сссылки на данные, как и ссылки на исполняемый код - безусловно являются данными. или что ты имел в виду?
пусть у нас есть 32 числа, которые нужно перемножить. то есть, нужно выполнить 31 перемножение. допустим один процессор у нас справляется с одним пермножением за 1 секунду, значит он затратит на все вычисления 31 сукунду. а что, если у нас в распоряжени есть 4 процессора? воспользуемся популярной сейчас серебрянной пулей - паттерном "разделяй и влавствуй" или в оригинале "map-reduce". ведущий процессор выдаёт для всех четырёх задания (map) в виде 8 чисел, которые следует перемножить. соответственно, через 8 секунд у каждого процессора будет результат, который он передаёт ведущему процессору, который перемножает полученные 4 числа (reduce) и ещё через 4 секунды получает ответ. итого - 12 секунд. не смотря, на увеличение производственных мощностей в 4 раза вычисления ускорились чуть более чем в два. причина тут кроется в том, что процесс редуцирования производил один процессор, а остальные в это время занимались какими-то своими делами. если редуцирование само замапить (выдать двум процессорам по два числа), то можно сэкономить ещё 2 секунды и добиться тем самым трёхкратного ускорения по сравнению с одним процессором. попробуем отказаться от идеи замапить сразу всё. вместо этого ведущй процессор просто разобьёт множество ведомых на две части и выдаст каждой группе по заданию в 16 чисел. внутри групп задания аналогично будут поделены на две части и так далее. в результате, у каждого процессора окажется по 8 чисел и по истечении 8 секунд - у четырёх процессоров будет 4 числа. далее каждый ведомый процессор в группе передаёт число лидеру группы и ещё через 1 секунду у нас остаётся два числа у двух процессоров. ещё секунда и у нас готов ответ. казалось бы, те же 10 секунд, но есть пара моментов, которы я не учитывал при описании... 1. при мапоредьюсе ведущий процессор должен знать о кажом ведомом процессоре и иметь прямой канал к нему. фрактальный же алгоритм распараллеливания предполагает, что каждый процессор знает только двоих ведомых - лидеров ведомых групп. это значительно упрощает организацию маршрутизации сообщений. 2. в итеративном мапоредьюсе ведущий процессор выступает в роли глобального хаба, гоняя траффик туда-сюда. при фрактальной организации все сообщения идут напрямую к адресату - тому процессору, которому с этими данными предстоит работать. мораль сей басни такова: нет смысла сразу пытаться плодить десяток потоков работающих с одними и теми же данными - лучше разбить программу на два как можно менее связных потока, каждый из которых ещё на два и так далее, пока не кончатся процессоры.
Так зачем тогда каждый раз их копировать, если можно копировать ссылку? PS. Пеши исчо. Только ставь пустые строчки между абзацами и предложения с заглавных букв начинай
если два процесса/объекта будут иметь ссылку на одну и ту же область памяти - один из них может данные изменить, а другому придётся это расхлёбывать. если данные копировать или ссылку перемещать, то проблем не возникает.
Для этого есть симофоры и система блокировок. Multithreading это преимущество, не надо позиционировать его как недостаток
дык в том-то и дело, что семафоры - это кривая реализация того, о чём я говорю, за одним маленьким исключением - ссылка на данные есть у всех потоков и им приходится с помощью семофоров блокировать доступ другим (которые будут с некоторым периодом пинговать семафор в ожидании открытия доступа). в моём же случае - ссылка есть только у одного процесса. а другие не имеют доступа потому, что ссылки у них нет. кроме того, в случае семафоров есть нетривиальная задача определения того, какому процессу освобождать память.
Amian, ну, не такой уж и большой, особенно если сообразить аццкий оптимизатор ;-) продолжим... программируя на си-подобных языках вечно испытываешь когнитивный диссонанс при осознании того, что, например, амперсанд используется для побитовых операций, а двойной амперсанд - для логических, в то время как побитовые операции при высокоуровневом программировании не слишком-то и актуальны. но самое печальное - не это, а то, что единожды заданное разработчиками языка поведение этих символов нельзя модифицировать под свои нужды. вялой попыткой исправить ситуацию является возможность перегрузить оператор для определённого класса. но это не решает проблемы полностью - оператор перегружается глобально, а это значит, что если мы подключим два разных класса, которые по разному же перегружают один и тот же оператор, то в нашем коде получится смешение разных стилей кодирования, что будет порождать путаницу и в конечном счёте - ошибки. вместо этого, удобнее было бы перегружать операторы локально. тогда можно было бы гарантировать логически однородное их поведение по отношению к любым подключаемым классам. примерный иллюстрирующий код: [js] $face.complement: compl: # определеям интерфейс и его локальный короткий алиас add sub mult div :compl $class.number: numb: # определяем класс и его локальный короткий алиас $face.complement.add| add| # определяем метод и его короткий локальный алиас # тут выполняем сложение чисел |add $face.complement.sub| sub| # тут выполняем вычитание чисел |sub :numb $class.string: str: $face.complement.add| add| # тут выполняем соединение строк |add :str con: $lib.stdio.console # короткий алиас для консоли ввода/вывода a: $class.number.create # создаём число b: 0 # то же самое con< a+b # ошибка, операция "+" не определена + : $face.complement.add # короткий алиас для метода сложения con< a+b # сложит два числа и выведет на экран con< a $face.complement.sub b # вычтет второе число из первого и выведет на экран a: $class.string.create # создаём сроку b: '' # то же самое con< a+b # соединит две строки и выведет на экран [/js] тут я, правда, немного утрировал. например, нет определения, что угловая скобка - это алиас для $face.message.send доллар - это обращение ко глобальной ( в рамках модуля ) переменной двоеточие - присваивание вертикальная черта - присваивание функции (двоеточие присвоило бы результат выполнения функции) в общем, всё это пока ещё криво, но идея я думаю ясна.
методы объекта можно условно разделить на два типа: мутаторы - методы изменяющие состояние объекта акцессоры - методы, не меняющие состояния объекта, создающие другие объекты эти определния можно расширить: мутаторы - функции, меняющие внешнее (относительно тела функции) состояние акцессоры - соответственно, не меняющие основное отличие функционального программирования от императивного заключается в том, что в фп применяются исключительно акцессоры, а в императивном - и то и другое. замечу, что многие императивные языки позволяют писать код исключительно на акцессорах, и поэтому позиционируются как "мультипарадигменные". однако, это заблуждение. основная фишка фп заключается не в том, что ни одна функция не изменяет внешнего состояния, а в том, что она *не может* изменить его. в этом смысле, на большинстве "мультипарадигменных" языков не возможно написать "функциональный код", так как глядя на функцию невозможно определить изменится ли какое-то внешнее состояние при её выполнени, или не изменится. действительно мультипарадигменным языком можно назвать только такой язык, который поддерживает следующие фишки: * объявление констант ( в отличие от переменной, которую никто не хочет изменять, константу изменить невозможно ) * объявление функций как акцессоров ( при попытке изменения внешнего состояния должна генерироваться ошибка )
а я уже давно писал в intel и amd, чтобы они разработали микруху с динамическим изменением количества ядер... пока молчат паразиты...
я имею ввиду динамически во время работы программы, а ПЛИС надо оптимизировать каждый раз кода поменяется количество чисел, не 32 а 16 например - это совсем другое...
о мой бог, вопрос космической важности! понятие thread - знакомо? и без всяких понтовых "мар_редьюс". Это первое. Второе, в Winnt очень хороший планировщик, он перекинет код на тот процессор, который свободен, в сочетании с дополнительными thread'ами дурацкие вопросы отпадают. Причем вопросы низкоуровневые, которые вообще вроде не должны касаться уровня потоков и регистров в мега-ультра-гипер-квадро-гига-супер-труе языке.
нет хуже языка, чем язык оторванный от реальности. язык должен предоставлять возможность разбивать поток выполнения программы на произвольное, не известное заранее, количество нитей. планировщик winnt такое умеет?