2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




На страницу Пред.  1 ... 45, 46, 47, 48, 49, 50, 51 ... 59  След.
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 18:07 
wrest в сообщении #1719822 писал(а):
А что, если факторизацию чисел цепочки делать parfor-ом, и прерывать parfor если какое-то факторизовалось не как надо?
А как оборвать не только parfor, но и запущенный в нём унутри factor?! Я способа не знаю. Оно даже по Ctrl+C не всегда обрывается.

Но вообще это самая правильная идея, запускать факторизацию в отдельных потоках и обрывать все их скопом при первой же "ошибке" (причине отброса цепочки) в любом потоке. Я предлагал такое сделать Хуго в его pcoul в теме пентадекатлона, но до него то ли не дошла выгода, то ли он недопонял идею, то ли у него это уже и сделано. На C/ASM под WinAPI я знаю как такое сделать, на PARI нет - без понятия как запустить дочерний процесс/поток и ждать его завершения, скорее всего стандартных средств просто нет, типа используйте parXXX функции и не парьтесь, но parfactor и parnumdiv отсутствуют.

-- 10.03.2026, 18:12 --

Yadryara в сообщении #1719825 писал(а):
70 дней вместо 100 — это ускорение почти на 43%, а не на 30%.
Соглашусь, если речь про ускорение (изменение скорости работы), то так и есть.
Но часто путается ускорение (изменение скорости) с "получить результат на 30% быстрее", т.е. затратить на 30% меньше времени, и вот тогда будет именно 70 дней, не 77.
И путается ещё и потому что в плюс оно совпадает: +30% равно умножению на 1.3. А вот в минус - нет, не совпадает, -30% не равно делению на 1.3. И вот неочевидность последнего и путает.

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 18:30 
Yadryara в сообщении #1719825 писал(а):
Моё мнение не изменилось. 70 дней вместо 100 — это ускорение почти на 43%, а не на 30%. А у вас другое мнение или это просто небрежность/пофигизм?

Если вместо 100 дней работа делается 70 , то ускорение темпа работы на 30%
А если вместо 70 дней работа делается за 100, то замедление темпа работы на 43%
Тут двух мнений быть не может, имхо.
Вы считаете скорости (работ в час) а не темпы (часов на работу) - ну, ваше право :D
В некоторых культурах вот считают потребление авто не в объеме топлива на расстояние (литрах на километры), а в расстояниях на объём (милях на галлоны). Нам их не понять...

-- 10.03.2026, 18:32 --

Dmitriy40 в сообщении #1719828 писал(а):
А как оборвать не только parfor, но и запущенный в нём унутри factor?! Я способа не знаю. Оно даже по Ctrl+C не всегда обрывается.

Тут я не знаю... Надо проверять. Думаете, со временем наберется зависших factor-ов, которые всё забьют?

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 20:05 
wrest в сообщении #1719830 писал(а):
Тут я не знаю... Надо проверять. Думаете, со временем наберется зависших factor-ов, которые всё забьют?
Да я вообще не понимаю как Вы собрались обрывать другие итерации parfor, у меня они все отрабатывают до конца:
Код:
nth=4;\\Желаемое количество потоков
default(nbthreads,nth);
allocatemem(10^8);
t0=getwalltime();
parfor(d=0,19, my(nd); print1(nd=numdiv(909165008476014999590146574242966924037355637363444071390071+d),", "); if(nd<>192, break); ); print;
print(nth," threads, time: ",strtime(getwalltime()-t0));
quit;


>gpp -q zf.gp
  ***   Warning: new stack size = 100000000 (95.367 Mbytes).
4, 384, 16, 32, 48, 24, 16, 768, 32, 1024, 8, 16, 2, 96, 8, 512, 80, 256, 32, 64,
1 threads, time: 27,792 ms

>gpp -q zf.gp
  ***   Warning: new stack size = 100000000 (95.367 Mbytes).
32, 48, 16, 384, 768, 16, 32, 24, 1024, 2, 96, 8, 512, 80, 256, 32, 16, 64, 8, 4,
4 threads, time: 8,583 ms

>gpp -q zf.gp
  ***   Warning: new stack size = 100000000 (95.367 Mbytes).
32, 48, 8, 2, 80, 96, 768, 512, 16, 32, 256, 384, 32, 1024, 16, 24, 64, 16, 8, 4,
24 threads, time: 9,561 ms
Видите, даже в один поток parfor не обрывается.

Для сравнения тот же код с обычным for:
Код:
>gpp -q zf.gp
  ***   Warning: new stack size = 100000000 (95.367 Mbytes).
4,
1 threads, time: 7,482 ms


-- 10.03.2026, 20:48 --

С другой стороны, в sequential части break вполне себе работает:
Код:
...
parfor(d=0,19, my(nd); nd=numdiv(909165008476014999590146574242966924037355637363444071390071+d); nd, t, print1(t,", "); if(t<>192, break); ); print;
...


>gpp -q zf.gp
  ***   Warning: new stack size = 100000000 (95.367 Mbytes).
32, 16, 384, 4,
24 threads, time: 9,554 ms
Оборвалось после 4-го так как у меня лишь 4 ядра процессора - и они все таки досчитались до конца и лишь новые не стали запускаться.
Т.е. запуск на многопотоковых процессорах выигрыша не даст, все итерации сумеют запуститься и досчитают до конца.
Да ещё и в конце большинство ядер будут простаивать ожидая завершения всего parfor, самой медленной итерации.
Так что для PARI это очень сомнительная идея, проблем больше выигрыша, имхо.

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 21:44 
Dmitriy40 в сообщении #1719838 писал(а):
Т.е. запуск на многопотоковых процессорах выигрыша не даст, все итерации сумеют запуститься и досчитают до конца.

Да, похоже на то, что запущенные в parfor вычисления не прерываются при помощи break и next.
Видимо, вместо них, надо палкой по голове генерить ошибку и ловить её. Например:
  1. ? iferr(parfor(d=0,19, print("d=",d);numdiv(909165008476014999590146574242966924037355637363444071390071+d),r,print("r=",r);if(r<>192,error("d=",d))),E,print(E));print("Continue computations") 
  2. d=0 
  3. d=1 
  4. d=3 
  5. d=5 
  6. d=6 
  7. d=2 
  8. d=7 
  9. d=4 
  10. r=32 
  11. error("user error: d=3") 
  12. Continue computations 
  13. cpu time = 25 ms, real time = 11 ms. 

Как видим, запустилось 8 вычислений, и прервалось норм, на d=3 которое раскладывается быстрее всех :D

-- 10.03.2026, 21:49 --

Dmitriy40 в сообщении #1719838 писал(а):
Т.е. запуск на многопотоковых процессорах выигрыша не даст, все итерации сумеют запуститься и досчитают до конца.

Ну... Видать break и next посылают слабые сигналы. Я сперва на ноль делил вместо break, тоже срабатывает мгновенно. Против лома нет приема. Ну и Ctrl-C, у меня по крайней мере, работает чотко. :mrgreen:

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 22:03 
Да, про error() я не подумал.

wrest
Хот Ваш под gpp (многопоточная версия PARI под винду) работает некорректно - вылетает по ошибке в винду и программа не продолжается. А под обычным gp64 - корректно.

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 22:07 
Dmitriy40 в сообщении #1719846 писал(а):
Хот Ваш под gpp (многопоточная версия PARI под винду) работает некорректно - вылетает по ошибке в винду и программа не продолжается.

Ну то есть в многопоточном pari под венду iferr не работает?

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 22:12 
wrest в сообщении #1719847 писал(а):
Ну то есть в многопоточном pari под венду iferr не работает?
Вроде того: не перехватывает такую ошибку от error(), та улетает в gpp и тот закрывается виндой по ошибке.
Хотя в один поток (nbthreads=1) работает.
В два потока виснет после первой итерации (выдаёт 384 делителя и подвисает).
В три и более потоков - вылетает в винду, успевая подсчитать одну итерацию (разную).

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 22:15 
Dmitriy40 в сообщении #1719848 писал(а):
Вроде того: не перехватывает такую ошибку от error(), та улетает в gpp и тот закрывается виндой по ошибке.

Ну хорошо, а если на ноль делить вместо break? Но вообще конечно странно это. Это ж юзерская ошибка, должно выпадать, если летит мимо iferr, в промпт интерпретатора.
Я даже где-то использовал пользовательские ошибки раньше для раннего прерывания.
P.S. Переходите на линукс для pari. :wink:

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 22:21 
wrest в сообщении #1719850 писал(а):
P.S. Переходите на линукс для pari. :wink:
Вы хотели сказать на С вместо PARI. :mrgreen:

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 22:22 
Dmitriy40 в сообщении #1719851 писал(а):
Вы хотели сказать на С вместо PARI.

На Си вам придётся тоже перейти на линукс ибо GMP нет под венду. Ну и мучиться потом с GMP, как Хьюго в pcoul. Хотя может он и не мучился, а было легко и приятно, просто заюзал какую-то другую библиотеку которая юзала GMP...

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 22:23 
wrest в сообщении #1719850 писал(а):
в промпт интерпретатора.
Я запускаю не из интерпретатора, а из командной строки: gpp.exe -q file.gp

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 22:27 
Dmitriy40 в сообщении #1719853 писал(а):
Я запускаю не из интерпретатора, а из командной строки: gpp.exe -q file.gp

Так попробуйте в интерпретаторе.

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 22:27 
wrest в сообщении #1719852 писал(а):
ибо GMP нет под венду.
Разве что-то мешает скомпилить под винду? Ну и свет клином на GMP не сошёлся, уж не может быть не быть библиотек длинной арифметики под винду, да сразу и с ECM факторизацией. Да из того же PARI из исходников вытащить и допилить (хотя конечно задачка весьма так себе, да).

-- 10.03.2026, 22:28 --

wrest в сообщении #1719854 писал(а):
Так попробуйте в интерпретаторе.
Тоже вылетает в винду (консоль).

-- 10.03.2026, 22:33 --

Хотя такой код работает:
Код:
iferr(parfor(d=0,19, 1/0, r, print(r)), E, print(E));
print("Continue.");

Получается дело в factor или error?

-- 10.03.2026, 22:37 --

И такой тоже работает:
Код:
iferr(parfor(d=0,19, error(d), r, print(r)), E, print(E));

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 22:33 
Dmitriy40 в сообщении #1719848 писал(а):
В три и более потоков - вылетает в винду, успевая подсчитать одну итерацию (разную).

А, так может оно выкидывает две ошибки, или типа того. Тут конечно разница в ОС сказывается т.к. у вас транслируется один API в другой... У Yadryara, кстати, примерно так же сейчас ибо у него на WSL1 -- а там не "полноценная" виртуализация, а трансляция системных вызовов, примерно как и в mingw у вас, остается надеяться что в Microsoft всё норм написали.

 
 
 
 Re: Как писать быстрые программы
Сообщение10.03.2026, 22:40 
Не, дело не в factor и numdiv, а во времени: если они выполняются быстро, то всё работает, а если больше секунды (ну или сколько не знаю) - то вылет gpp.exe.
Например заменив аргумент numdiv на 2^d+1 - работает.

 
 
 [ Сообщений: 874 ]  На страницу Пред.  1 ... 45, 46, 47, 48, 49, 50, 51 ... 59  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group