Advanced member
Статус: Не в сети Регистрация: 09.03.2004 Откуда: Кишинёв
Root Для универсальности да, но для скорости, по идее, нет там туева куча вызовов(с параметрами). У меня по сути тоже самое только без вызовов. Думаю это важный момент. Я же говорю что добавление в конец макроса дополнительного сравнения(просто if(nx==N){...}) в полтора раза замедляет выполнение. Думаю рекурсия ещё сильнее усугубит дело. Да и не люблю я её - ничерта не понятно.
Кстати по поводу макросов: есть и минусы. Отладка серьёзно усложнилась(дебагер по строкам кода бегает и внутрь макроса не заглядывает), тоже самое для дизасебли вида - код всего макроса, а не отдельных частей.
Advanced member
Статус: Не в сети Регистрация: 09.03.2004 Откуда: Кишинёв
Black_mirror Достойно.
Цитата:
Если первого ферзя ставить только на половину клеток первого ряда, то можно ускорить алгоритм в два раза, другая половина вариантов будет зеркальным отражением. Если число клеток нечётное и первый ферзь стоит посередине ряда, то в этом случае для второго ферзя нужно перебрать только половину клеток второго ряда.
Думаю если это ко мне прикрутить то до твоего уровня доберусь легко, а дальше посмотрим. Добавлено спустя 12 минут, 59 секунд Black_mirror кстати я порог в 10 секунд у себя преодолел для N=15 и у меня не двухядерник . Но конечно же твоя быстрее раза в 2.5.
Advanced member
Статус: Не в сети Регистрация: 09.03.2004 Откуда: Кишинёв
Теперь и я считаю до половины + провёл небольшую переделку. Ожидал существенного прироста, но получил всего процентов 15 от этой переделки . В общем в архиве две программы для N=15 и N=16. Ввиду того что при N=15 уже получается слишком быстро считаю целесообразным переходить только на N=16. Мои результаты на неразогнанном A643000+: N=15: ~3.95 сек N=16: ~25 сек В среднем отстование от варианта Black_mirror чють больше чем в два раза. Брать тут.
Глянул на код который генерит Visual С: он большую часть циклов просто тупо раскрывает (это с включенной оптимизацией на скорость) и это существенно помогает. Дальше программно "боротся" с Black_mirror будет сложно. Почитаю умные книжки по теории, может чего вычитаю. По другому с голым ассемблером трудно будет совладать.
Переходим к тяжелой артилерии . Такой вопрос: если просто разбить действие на два потока и запустить на двухпроцессорной системе эти потоки лягут каждый на ядро или могут запустится на одном и том же? Или по другому: нужно ли непосредственно указывать какому потоку на каком ядре работать?
Member
Статус: Не в сети Регистрация: 31.01.2004 Откуда: moskow
Цитата:
если просто разбить действие на два потока и запустить на двухпроцессорной системе эти потоки лягут каждый на ядро или могут запустится на одном и том же? Или по другому: нужно ли непосредственно указывать какому потоку на каком ядре работать?
На дельфях я никогда не указывал, делал до 4-х потоков и все ложится на свой ЦПУ, проверял на 2х265, 2х270 Оптеронах(4 ядра) и на своем 4400+(2 ядра)... Вроде винда по уму разруливает...
Добавлено спустя 7 минут, 48 секунд твоя Q=16 у меня на celerone-D 3600=20,53s
15--->3.33cek
Добавлено спустя 1 минуту, 44 секунды Его Q15=2,015 сек
Q16=13,625sec
Хорошо вам говорить, Q16 , у меня Q15 из 100 сек. не выходит... -) Добавлено спустя 17 минут, 43 секунды Есть Q16! - 775,594сек
Advanced member
Статус: Не в сети Регистрация: 30.08.2003 Откуда: Санкт-Петербург
mein
Цитата:
Переходим к тяжелой артилерии . Такой вопрос: если просто разбить действие на два потока и запустить на двухпроцессорной системе эти потоки лягут каждый на ядро или могут запустится на одном и том же? Или по другому: нужно ли непосредственно указывать какому потоку на каком ядре работать?
а) могут запуститься и на одном, но это зависит от загрузки обоих процов. Т.е. в стандартном случае они распараллелятся. б) нет, не обязательно. Хотя вроде можно и самому (напр., даже в Task Manager есть функция Set Affinity, т.е. привязать процесс к какому-то определенному процу, ИМХО, такое же можно делать с потоками, но надо читать MSDN) Добавлено спустя 4 минуты, 20 секунд Black_mirror работает! fx1 2279184 2000ms 1'139'592var/sec fx2 2279184 1015ms 2'245'501var/sec fx4 2279184 1016ms 2'243'291var/sec
_________________ {:€ дед в законе :-) нородный окодемег почетный пользователь OpenSuSE 11.3 Ремонт и модернизация ноутбуков IBM (Lenovo) ThinkPad
Member
Статус: Не в сети Регистрация: 31.01.2004 Откуда: moskow
mein по моему там че то нереальное... как можно расставить 32 Ферзя на P4-1500Mhz За 33 секунды?!?!?!
А алгоритм на рисунке есть, тока я пока его не до конца понял, он для С++ приведен.
http://images.people.overclockers.ru/82395.gif
Последний раз редактировалось Locki 19.07.2006 13:38, всего редактировалось 1 раз.
Member
Статус: Не в сети Регистрация: 31.01.2004 Откуда: moskow
Как вам это:
Цитата:
The final version of the algorithm is capable of solving the n-queens problem in a linear time. On an IBM RS6000, it takes around 55s to find a solution to the problem size of 3,000,000. An initial description of the algorithm can be found in R. Sosic and J. Gu. 3,000,000 Queens in Less Than One Minute. SIGART Bulletin, Vol. 2, 2, pp. 22-24, Apr, 1991.
A description of improvements and an analysis of the algorithm behavior can be found in R. Sosic and J. Gu. Fast Search Algorithms for the N-Queens Problem. IEEE Transactions on Systems, Man, and Cybernetics. Vol. 21, 6, pp. 1572-1576, Nov/Dec, 1991. Кратко: В 1991 году был придуман алгоритм, благодаря которому стало возможным 3 млн ферзей расставить за 55сек на комппе IBM RS6000. Описание можно найти "там то и там то"... -)
Advanced member
Статус: Не в сети Регистрация: 09.03.2004 Откуда: Кишинёв
Locki Найти расстановку это не одно и тоже как сосчитать все растановки. Наверное на фцэнтре такой же вариант - просто нахождение первой валидной расстановки
Black_mirror Твои последнии варианты (многопоточные) глючат: ввожу N=14 (или 17, например) и получаю постоянно разные ответы (иногда проскакивает правильный).
mein писал(а):
Глянул на код который генерит Visual С: он большую часть циклов просто тупо раскрывает (это с включенной оптимизацией на скорость) и это существенно помогает. Дальше программно "боротся" с Black_mirror будет сложно. Почитаю умные книжки по теории, может чего вычитаю. По другому с голым ассемблером трудно будет совладать.
У Black_mirror по всей видимости немного другой способ проверки битого поля, так что ассеблер тут выигрыш не сильно даёт. Вот набросал для сравнения на C++:
Код:
#include <iostream> #include <windows.h>
using namespace std;
unsigned N, count = 0;
void placeQueen( unsigned col, unsigned ls, unsigned ns, unsigned rs ) { if ( col == N ) { ++count; return; }
cout << count << " placings at all.\n" << time1 - time0 << " ms passed.\n"; }
Проигрыш ассемблерному варианту Black_mirror примерно 10%. Можно попробовать раскрыть рекурсию в циклы, тогда, глядишь, ещё и в выигрыше будем.
З.Ы. Изменил текст на первый вариант. Скорость я сравнивал именно с ним. Почему-то небольшие изменения (по сути только ~ в другом месте сделал) во втором варианте увеличили время для 15 ферзей с 2.033 до 2.495... Видимо, какая-то хитрая оптимизация от microsoft'а.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 28
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения