|
|
|
Построение фрактала Мандельброта20.01.2013, 18:45. Показов 21714. Ответов 220
Метки нет (Все метки)
Добавил поток для построения, но рано обрадовался: прога как зависала, так виснет и сейчас.
И как использовать все ядра процессора на все 100? Кто-нибудь знает?
0
|
|
| 20.01.2013, 18:45 | |
|
Ответы с готовыми решениями:
220
Построение фрактала Коха (основа - правильный треугольник)
Генерация фрактала Мандельброта. NASM + OpenGL |
|
Модератор
3492 / 2614 / 742
Регистрация: 19.09.2012
Сообщений: 7,977
|
|
| 02.04.2013, 17:53 | |
|
0
|
|
|
Модератор
3492 / 2614 / 742
Регистрация: 19.09.2012
Сообщений: 7,977
|
||||||
| 02.04.2013, 22:40 | ||||||
|
Собственно, теорию взял тут (см. рис.):
http://en.wikipedia.org/wiki/M... te_note-23 Оказалось, что Z - это Zn, при котором выполняется условие (Sqr(z.Re) + Sqr(z.Im) > 4). Отсюда вытекает основная проблема - ассемблерная вставка для вычисления n, собственно, возвращает только n (без Z), поэтому пришлось взять ее дельфийский вариант для экспериментов. Получился следующий код:
?
0
|
||||||
|
Модератор
3492 / 2614 / 742
Регистрация: 19.09.2012
Сообщений: 7,977
|
|
| 04.04.2013, 12:28 | |
|
FadeDemon, прикрутил твою процедуру fractal_mandelbrot_fast к своему коду для сравнения.
Получилось (при прочих равных условиях), что с твоим кодом выигрыш ~18%:
0
|
|
|
60 / 0 / 1
Регистрация: 31.03.2013
Сообщений: 5
|
|||||||
| 04.04.2013, 22:53 | |||||||
|
Блин, столько писал, писал, а форум взял все и не отправил
![]() Если там у тебя ассемблерная вставка на FPU которую я гдето видел, то это есть почти чистый выигрыш SSE перед FPU, ибо память в ней у тебя почти не используется, вроде (а я в стате приводил разницу между полностью наивным вариантом на дельфи, и с максимальными SSEшными наворотами).. Да и мой код как я говорил не претендует на идеальный Не думаю вообще что можно вытянуть больше чем эти 18%, я не представляю от чего ещё можно избавиться ради лишних наносекундок, но впринципе чего не получилось у меня, может и получиться у тебя.Тут ещё есть некоторые идеи насчет плавных цветов, я если честно только тут про эту вещь и узнал ![]() Во первых, константу, с которой мы сравниваем модуль, надо вместо 2 побольше брать, к примеру 16 или 32 (об этом кстати в википедии и пишут), плюс, от корня можно точно также избавиться как и раньше, по правилам математики - корень это степень 1/2, а степень аргумента можно вынести за логарифм, плюс ещё некоторые преобразования, и формула вырождается примерно вот в это (только что проверял, сей код - темпоральный вариант):
Тут функция цвета (sin(n * 7) + 1) * 127, у тебя на картинке выше думаю полоски (хотя они конечно еле заметны) на сглаженном варианте уйдут полностью, думаю. Остаеётся только проблема оптимизации подсчета логарифма, и тут я пока вижу 3 варианта (мне тоже захотелось себе такую гладкую штучку, очень захотелось): 1. Ряд тейлора и его модификации - вариант мертворожденный, ибо сам ряд расходиться, а модификации очень ресурсоёмки... 2. Метод ньютона для уравнения e^x - аргумент = 0, вариант как я обнаружил, в целом приемлимый, ряд тейлора экспоненты (экспоненту тоже только через FPU считать) нормально сходиться на ~8 итерациях, а итераций метода ньютона хватает 2 - но правда это для диапазона от 8 до 16, а если брать ту самую 1024... в общем печаль, обида, и досада, хотя если опдумать, то n > 1024 можно делить на собстно 1024, и получим интервал от ~1 до ~2, а деление можно легко компенсировать, прибавив к результату log(1024). Так, что не все тут потеряно. 3. Ну и мне кажется самый вероятный метод, это из SSE переключаться в FPU, и считать логарифм его вшитыми средствами но проблема в том, что нету команд, напрямую переписывающих значения из XMM регистров в FPU стек, только в MMX регисты, а данные в FPU стеке храняться в Extended формате (80 бит), а MMX регистры всего лишь 64 бит имеют размер, плюс командой EMMS весь FPU стек помечается свободным, а без нее он, грубо выражаясь, не работает... В общем тоже не так тут все просто...4. В инете вроде есть готовые реализации логарифма на SSE. Если ничего не получиться, можно обратиться и к ним... Весь день над этим ломаю голову, в общем. Ещё я тоже начал размышлять над многопоточным и прогрессивным рисованием, у меня рисование по отдельным пикселям уже есть, осталось все это склеить, и получиться даже православнее чем Fractal eXtreme, я думаю Для правильной синхронизации потоков мне вообще пришла идея копать в сторону семафоров.. Но это как будет время, может в следующей статье выкладу, придется довольно основательно мою прогу переделать, и мега-ассемберную вставочку перебрать, плюс там пара багов есть с округлением в наложении цвета.
0
|
|||||||
|
Модератор
3492 / 2614 / 742
Регистрация: 19.09.2012
Сообщений: 7,977
|
||||||||
| 05.04.2013, 12:07 | ||||||||
|
Сравнивал fractal_mandelbrot_fast с ассемблерной вставкой на FPU, обернутой в 2 дельфийских цикла и с вариантом прогрессивного построения с одним потоком - результаты одинаковые - 18-20%. Думаю если циклы сделать на ASM, то процент немного сократится, но разница все равно существенная будет. По поводу Smooth Coloring... Последовал твоему совету и увеличил константу - результат отличный. Вообще в Инете видел много разных вариаций с логарифмами, даже вариант после нахождения |Zn|>2 еще пару циклов прокрутить (видимо, это аналог увеличению константы). Сам пока остановился примерно на таком варианте:
.На счет оптимизации подсчета логарифма ничего умного не скажу, кроме как лог. в знаменателе посчитать заранее . Вчера три часа потратил только на то, чтобы разобраться как работает вставка на FPU, чтобы Z оттуда добыть. Поэтому для меня будет хорошо, если я эти логарифмы хотя бы на FPU реализую.Еще один глобальный вопрос, который хотелось бы обсудить: Переменные типа Double (да и Extended тоже) позволяют увеличивать фрактал лишь до определенных пределов. А как продвинуться дальше? Есть какие идеи?
0
|
||||||||
|
Модератор
3492 / 2614 / 742
Регистрация: 19.09.2012
Сообщений: 7,977
|
|
| 05.04.2013, 18:07 | |
|
Попытки вытащить |Zn| из ASM успехом не увенчались, чувствую нужна помощь зала
.Зато получилась достаточно забавная разновидность фрактала:
0
|
|
|
60 / 0 / 1
Регистрация: 31.03.2013
Сообщений: 5
|
|||||||||||||||||||||||
| 05.04.2013, 19:30 | |||||||||||||||||||||||
|
Можно поступить, как у нас в институте поступает препод вычмата, готовящий олимпиадников по програмированию: написать программу, которая реализует все базовые операции на больших (строго говоря любого размера) числах, заданных в строчку, то-есть например такая программа без труда сложит число запись которого в длинну несколько мегабайт, или по другому у него миллион знаков.. Более того, я думаю в инете подобных вещей навалом. Можно немного оптимизировать, записывая число не в строчку, а как положено, битами, но толко складывать/умножать по своим правилам, кстати, как минимум сложение таких длинных оптимизированных чисел можно сказать уже реализовано в архитектуре x86, там существуют такие команды как ADD и ADC, первая - обыкновенное сложение, а вот вторая - прибавление флага переноса (флага CF), который как раз выставляется командой ADD при возникновении переполнения. Умные компиляторы (делфи 7 кстати тоже) сложение/вычитание 64-битных чисел на 32-битных программах делают именно так, кстати (в x64 там с такими числами проблем по понятным причинам нету ). Понятно становиться, что с помощью большого кол-ва последовательно стоящих ADD/ADC можно складывать числа абсолютно произвольной длинны - все будет работать корректно. С умножением таких вещей сложнее, но делфи к примеру тоже умножение 64битных чисел как то делает, с помощью 32 битных команд (только что посмотрел, FPU там не используется), если разобраться как, то можно расширить и на произвольные числа, но это касается только целых числел, а нам нужны не целые....И тут у меня недавно возникла другая идея - изобрести свой тип float заново. Если коротко, то я думаю все знаем мы, что любой тип с плавающе точкой состоит из 3 вещей: мантиссы, порядка, и знакового бита. А ограничение, из-за которого фрактал нельзя увелчить больше положенного, возникает, как я понял, из-за того, что переполняется именно порядок, то-есть гдето в рачетах возникают числа по порядку меньшие чем 10-300 степени, которые тип Double перестает переваривать (Extended перестает переваривать числа порядка 10-4000), а все потому, что в этих типах для хранения порядка выделено совсем немного битов (для float - 8 бит, для дубла чуть побольше). С мантиссой, то-есть битами точности как мне кажется всё ок, их хвататет с избытком, и при увеличении порядка, мантисса то собственно не деградирует, допустим если умножить 0.256565 и 0.35678758, получиться примерно 0.0915392054627, в мантиссу запижется чтото типо 915392054627, и если умножить 0.000...(милион нулей)...00000256565 и 0.000...(милион нулей)...0000035678758, в мантиссу запишется то-же самое, но вот порядок.. в общем, вся загвоздка у нас в этом самом порядке, нам надо его значительно расширить. Как мне это представилось на конкретном примере. Делаем структуру, с двумя полями Int64. Одно будет у нас мантисса (и знак впридачу), другое будет у нас порядком. Я думаю 263 нулей нам хватит чтобы довольно долго крутить колесиком мыши, ну а если и этого будет мало, то можно вернуться к тому что я выше писал: вместо Int64 использовать искусственныеь длинные числа, уже так, как будет удобнее, которые дадут нам абсолютно произвольное количество нулей. Как только у нас появляется такая структура, мы можем ее считать в общем-то новым полноценным типом с плавающей точкой, нам остается только научить компьютер такие структуры вычитать, складывать, умножать, делить... Если мы научимся делать эти 4 базовые вещи, мы тут же научимся и возводить в целочисленную степень. А как только научимся возводить в степень, то немного покурив вычислительную математику, узнав что такое ряд тейлора и метод Ньютона, мы сможем на наших числах с легкостью определить такие вещи как синус, косинус, экспонента, логарифм и прочие взрочлые штуки (тут тольо оговориться надо, это будет работать ЛЮТО, БЕШЕНО, ЗВЕРСКИ НЕВЫНОСИМО МЕДЛЕННО, как впрочем и все наши операции с такими числами). Теперь, попробуем научиться такие структуры складывать, тут нам помогут некоторые школьные знания, и интуиция... Допусим, сначала попробуем разобраться, как же всетаки будут интуитивно представляться у нас числа с плавающей точкой. Рассмотрим число 1.0. В целом это то же самое что 1. Для его записи, в мантиссу мы поместим 1, а в порядок 0. Такая конфигурация значений у нас и будет означать 1.0, в нашем новом формате чисел. Чтобы закрепить понимание, рассмотрим числа 100.0 и 0.01. Весь прикол в том, что у всех трех рассмотренных чисел, мантисса будет равна 1, но у 100 - порядок будет 2, а у 0.01 - порядок -2. Это собствено нам вспоминается школьная арифметика: порядок есть ни что иное, как положение плавающей точки в числе. Настоящие числа, double например, устроены так же, или почти также, точно на этот счет не знаю. Но, такого как я описал представления, нам будет достаточно. Попробуем теперь числа 10 и 1 сложить. У обоих мантисса 1, у первого порядок 1, у второго 0. Что мы делаем: берем едицицу, двигаем в ней запятую на указаный порядок (то-есть умножаем ее на 10), и, собственно, обыкновенным сложением складываем. Записываем результат в мантиссу, а вот порядко в этом случае устанавливаем в 0, так как в мантиссе уже лежит число 11, и оно само автоматически имеет нужный порядок. Теперь другой пример: складываем 0.0000..(муллион нулей)..000001 и 1. Что тут можно сделать? Мы поступим по аналогии. В мантиссе у обоих чисел снова единицы. Но у первого порядок -1000000, у второго 0. Мы берем, и единицу миллион раз делим на 10. И то что получилось, прибавляем к единице, тоесть первому слагаемому, и выставляем его порядок. Нам здесь должно быть профиг, что от единицы, деленной миллион раз на 10 ничего не останется, на самом деле, точно такая же потеря точности происходит и в настоящих типах, и это совершенно нормально - в этом то и кроется секрет разделения числа на мантиссу (биты точности) и порядок (количество нулей, на которые эта точность уезжает). Попробуем теперь сложить 0.001 и 0.00001. У первого порядок -3, у второго -5. Что же мы делаем тут?... В мантиссе опять единицы. Но разница порядоков - 2. Получается, мы берем единицу, и делим ее 2 раза на 10, чтобы компенсировать разницу порядком, но мы помним тут еще, что мантисса и порядок у нас целые, и все наши манипуляции мы производим с целыми типами, и поэтому, чтобы корректно "поделить 1 на 100", мы на самом деле эту единицу трогать не будем, а умножим на 100 предыдущую, и запомним, что мы на 2 порядок увеличили. После сложения у нас получается 101, и это мы пишем в мантиссу, плюс мы помним, что задрали числу порядок на 2, а порядок бОльшего слагаемого, у нас был -3. Получается, мы возвращаем порядок на место, тоесть прибавляем к порядку -2, и добавляем туда -3, получается -5. И если руками сдвинуть запятую в 101 на 5 знаков назад, то получим, что мы не ошиблись, и у нас действительно получается 0.00101, что и должно было получиться. Брр... Аж глаза на лоб полезли от таких размышлений. В общем, вычитание можно определить аналогичным способом, для хранения знака можно использовать признак отрицательной мантиссы, например. Вот как именно определять умножение, так с ходу сказать не могу, могу только сказать что мантиссы там напрямую перемножаются, а порядки складываются, но дело все в том, что если мы попытаемся умножить 0xFFFFFFFFFFFFFFFF само на себя, то оно явно вылезет за пределы Int64, и нас постигнет фейл, поскольку это не потеря точноти будет - потеряются старшие биты. что делать с этим, я чесговоря не придумал..... Это все в общем так, размышления, вдруг у когонибуть появиться желание такое реализовать ![]() Такую вот арифметику вполне множно использовать для рассчета фрактала, и даже логарифмы на такой арифметике прикрутить, но опять повторюсь, работать это будет просто ЗВЕРСКИ медленно, учитывая что в наших текущих кодах, сложение-умножение выполняются по операции на одну команду процессора. С рядами тейлора - там вообще жесть, чтобы посчитать допустим экспоненту с нужной нам точности, нам фактически надо посчитать многочлен 9-10 степени, а то и побольше, что потребует собой 102 / 2 операций умножения (это если без схемы горнера, правда, по этой схеме многочлен можно вроде быстрее посчитать, за 10 умножений, не помню чтоно, это типо если икс за скобки максимально вынести), и 9 операций сложения, я уже не говорю что там на констаныт делить надо. И это только чтобы посчтить ОДНУ ЭКСПОНЕНТУ! А чтобы посчитать логарифм методом ньютона, придется сделать штук 5-6-20-100 итераций, тоесть посчитать столько же экспонент.... Это все ради только одного, единственного вызова логарифма, с нормальной точностью, которую нам вот гарантирует FPU. Причем заметим, всю эу порногорафию, FPU проделывает одной командой. ОДНОЙ. а сколько тут понадобиться нам.... ну думаю можно осознать всю серьезность проблемы. Так что задумка своей целочисленной арифметики - весьма спорная вещь. Но с другой стороны, очень интересная теоретически. Лично мне тоже интересно позумить наш фрактал, он ведь не полностью самоподобен то.... P.S прошу прощения за многабукав, привык целые статьи писать ![]() Кстати в конце добавить можно, что в инете полюбому можно найти готовые реализации библиотек для работы с большими числами, ну вот просто полюбому... и их уже использовать, чем наверно я и советую заняться, если чильно захочется такой высокозумленый фрактал. Но, написать своё - это всегда намного интересне... (по крайней мере мне )Добавлено через 17 минут
ах да, в отладчике делфи есть режим просмотра FPU - тыкаешь в асмокоде на какойнибуть строчке F4, потом Alt+Ctrl+C, и там Ctrl+U - вылезет FPU стек, я думаю наблюдая за ним можно понять, где там может храниться модуль... если вдруг он храниться не на вершине, то тогда:
0
|
|||||||||||||||||||||||
|
Модератор
3492 / 2614 / 742
Регистрация: 19.09.2012
Сообщений: 7,977
|
|||||||||||||
| 06.04.2013, 17:10 | |||||||||||||
|
Из ассемблерной вставки в локальную переменную Просмотрел через отладчик - оказывается fcomip st, st(5) выбрасывает нужное мне значение. Спасибо за совет. Надеюсь проблема только в этом. По зуму... Про "Длинную" арифметику я читал, коды различных операций есть. Но применительно к данной задаче - это, как мне кажется, не выход. Слишком все медленно будет работать. Если других вариантов нет, то это очень печально. Добавлено через 1 час 22 минуты Кликните здесь для просмотра всего текста
Надо добавить глобальную переменную ZZ: Double; и это будет |Zn|. Добавлено через 19 часов 2 минуты Переделал ASM вставку и добавил туда режим Smooth Coloring: Кликните здесь для просмотра всего текста
Smooth: boolean (глобальная) - включает режим. n: Double (локальная) - собственно n.
0
|
|||||||||||||
|
Модератор
3492 / 2614 / 742
Регистрация: 19.09.2012
Сообщений: 7,977
|
|||||||||||
| 07.04.2013, 21:33 | |||||||||||
|
Есть такая мысля:
Мы в своих расчетах используем числа, отличающиеся друг от друга лишь последними цифрами. Например, берем диапазон Re:
Из мат. операций мы используем только [+] [-][*], поэтому потери точности быть не должно. Отделять числа от основного надо по 9 цифр, т.к. мантисса (Extended) вмещает до 19 цифр, а макс. значение при перемножении числа из 9 цифр = 18. P.S. Устройство вещественных типов: http://www.delphikingdom.com/a... alogID=374
0
|
|||||||||||
|
Модератор
3492 / 2614 / 742
Регистрация: 19.09.2012
Сообщений: 7,977
|
|
| 09.04.2013, 21:17 | |
|
0
|
|
|
60 / 0 / 1
Регистрация: 31.03.2013
Сообщений: 5
|
|
| 10.04.2013, 07:00 | |
|
Проблема то не в мантиссе, проблема здесь исключительно в порядке, вернее в его переполнении, когда возникают числа меньше приблизительно 10-300, то порядок не может сместиться в меньшую сторону, и чтобы это компенсировать, страдать начинает мантисса, которую просто брутально сдвигают, компенсируя невозможность вместо этого уменьшать порядок, отсюда то и лезут потери точности... Поэтому тут просто надо научиться хранить "неограниченно длинный" порядок, как наиболее перспективный вариант, мне видиться самодельное "плавающее" число, представленное как структура из двух Int64, которые по отдельности будут отвечать за мантиссу и порядок, ну, как я выше писал... Разве что под порядок можно и по больше чисел выделить, например штуки 4 Int64, на дольше хватит
хотя, числа вида 10263 уже, в общем-то, внушают уважение..
0
|
|
|
Модератор
3492 / 2614 / 742
Регистрация: 19.09.2012
Сообщений: 7,977
|
|
| 10.04.2013, 10:07 | |
|
По моим прикидкам, проблема исключительно в мантиссе - не хватает цифр точности. При этом степень вообще практически не задействуется (см. рис.). Когда точность вычислений опускается ниже 19-й цифры (для Extended) все застопоривается.
0
|
|
|
726 / 478 / 130
Регистрация: 24.12.2008
Сообщений: 3,924
|
||||||
| 11.04.2013, 00:21 | ||||||
0
|
||||||
|
726 / 478 / 130
Регистрация: 24.12.2008
Сообщений: 3,924
|
|
| 12.04.2013, 16:06 | |
|
Поможет, еще быстрее будет через SetPixel или ScanLine Bitmap'а
0
|
|
|
|
|
| 15.04.2013, 14:05 [ТС] | |
|
Методы ускорения и оптимизации:
1) Проверка на симметрию - помогите, я там что-то написал - не получается ![]() 2) Проверка на периодичность(Periodicity Checking) - провера чёрных мест. Там какие-то уравнения, о них потом. С симметрией помогите, не получается.
0
|
|
| 15.04.2013, 14:05 | |
|
Написать код для создания фрактала Мандельброта и Кантора Построение фрактала
Построение трехмерного фрактала: как установить точки Построение фрактала «Треугольник Серпинского» с возможностью изменения числа образующих примитивов с помощью клавиш Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С.
Задача:
Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
|
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
|
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
|
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701
Купил два термопринтера QR701.
На сэлф-тесте написано:
Language: PC936 (GB18030).
Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
|
|
Создание формы заимствованного документа
Maks 03.08.2026
Задача:
Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также
табличная часть со следующими реквизитами:
- Расчетный счет покупателя. . .
|
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача:
В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
|
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов.
Логика кажется понятной:
1. Находим ключевые слова.
2. Добавляем их на. . .
|
Знание — сила: Доктрина интенциональности знаний, углубление в формулу
Hrethgir 01.08.2026
https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11957&stc=1&d=1785567302
Знаменитый афоризм Фрэнсиса Бэкона «Знание — сила» (Scientia potentia est) в массовой культуре принято понимать. . .
|