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

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




На страницу Пред.  1 ... 87, 88, 89, 90, 91, 92, 93, 94  След.
 Re: Как писать быстрые программы
Аватара пользователя
Спасибо! Сразу, чтобы сам файл не портить, сохранил в другом файле и хотел убедиться что он компилится и работает.

Код:
C:\FasmNew>fasm.exe HL1-1.asm
flat assembler  version 1.73.32  (1048576 kilobytes memory)
HL1-1.asm [3]:
include 'win64axp.inc'
error: file not found.

Вроде в таких случаях то ли путь надо в самом .asm прописать, то ли ещё что уже точно не помню.

 Re: Как писать быстрые программы
Как вариант можно в include указать файл с полным (или относительным от текущей папки) путём.
Например: include 'C:\Program Files (x86)\FASM\INCLUDE\win64axp.inc'
Или include 'INCLUDE\win64axp.inc' если в текущей папке есть папка INCLUDE и в ней файл win64axp.inc (хотя в таком случае должно было сработать и без указания пути).

-- добавлено через 8 минут --

Чтобы не размазывать один и тот же путь по всем исходникам я запускаю компиляцию не сразу fasm.exe, а через батник с содержимым:
Код:
@echo off
set INCLUDE=C:\Program Files (x86)\FASM\INCLUDE
"C:\Program Files (x86)\FASM\fasm.exe" -m 1700000 %*
Имя файла с исходным кодом указывается как обычно в параметрах запуска батника.
Тут ещё и памяти указано почти максимум возможного, 1.7ГБ.
Разумеется у Вас путь может быть другим.

 Re: Как писать быстрые программы
Аватара пользователя
Да, это быстро удалось преодолеть. ИИ тоже подсказал.

Но вот дальше всё равно скомпилить не удавалось. То одна ошибка, то другая. Я даже подумал что может вы не ту версию мне прислали. У вас-то она запросто компилится с первой попытки?

Потом подумал что может у нас с вами Фасмы разные и в этом всё дело.

ИИ подсказывал как исправить вашу программу. Раз десять исправлял. Ну в итоге она всё-таки скомпилилась, но, как и подумал, работать уже не захотела :-(

Так что планы по ускорению именно этого вашего кода зависли в самом начале.

 Re: Как писать быстрые программы
Да, у меня конечно же компилится.
И батником (как обычно), и если файл hl1-vc-time.asm без модификации положить в подпапку INCLUDE папки с fasm.exe и запустить компиляцию командой ..\fasm.exe hl1-vc-time.asm в папке INCLUDE.
FASM у меня 1.73.32, но в более новом 1.73.35 ничего принципиально не исправлялось, впрочем им тоже проверил, тоже компилится.

Yadryara в сообщении #1727605 писал(а):
ИИ подсказывал как исправить вашу программу. Раз десять исправлял.
Совершенно излишне.
Достаточно понимать как ищутся включаемые командой include файлы и обеспечить их доступность:
- или через переменную окружения INCLUDE как у меня в батнике выше,
- или сделав папку INCLUDE текущей,
- или изменив команду include в исходнике на include 'include\win64axp.inc' и положив исходник в папку с fasm.exe (это частный случай следующего метода),
- или указав в команде include полный путь к файлу win64axp.inc и тогда исходник может лежать где угодно.
Все эти варианты точно работают, только что проверил.
Так что исправлять либо вообще ничего не надо, либо всего одну строчку.
Вот именно так должен был ответить ИИ ... :mrgreen: Ну или хотя бы любым из этих вариантов благо они все рабочие.

 Re: Как писать быстрые программы
Аватара пользователя
Dmitriy40 в сообщении #1727621 писал(а):
FASM у меня 1.73.32,

Да, у меня тоже эта версия.

На этот раз я ему напоминал, что не надо трогать код Дмитрия. Но он меня всё-таки уговорил вставить после 3-й строки

Код:
macro stdcall proc,arg1 {
    fastcall proc,arg1
}

И программа не только скомпилилась, но и заработала с прежней скоростью.

 Re: Как писать быстрые программы
Yadryara в сообщении #1727638 писал(а):
Но он меня всё-таки уговорил вставить после 3-й строки
Не понимаю зачем, stdcall вполне себе объявлен в MACRO\PROC64.INC, который будет автоматически подключен файлом WIN64A.INC, который подключается как раз файлом WIN64AXP.INC, причём определение заметно другое:
macro stdcall args& { fastcall args }
Т.е. ничего добавлять не надо.
Ваш с ИИ вариант будет работать только пока аргумент вызова строго один. Вам повезло что в данном исходнике это везде так.

 Re: Как писать быстрые программы
Аватара пользователя
Dmitriy40 в сообщении #1727655 писал(а):
Не понимаю зачем,

Не работало по-другому. Но не вижу смысла сейчас сюда постить скриншоты об ошибках и вас напрягать. Тем более что они были преодолены. Пусть даже и кривовато.

Хотя ИИ мне советовал, спросите у Дмитрия то, спросите сё. Даже специальное обращение к вам подготовил.

Я говорю: "Дмитрий скорее всего скажет, что проще самому написать многопоточную версию чем объяснять как сделать".

В общем 7 попыток ИИ сделал, 7 новых прог по разным идеям написал, но все как одна безрезультатные — прога не ускорилась ни на йоту.

Подробнее не буду, здесь всё-таки тема не об ИИ.

 Re: Как писать быстрые программы
Да объяснить то не слишком сложно:
1. В Iterate() везде сделать чтобы если .my_n>1, то обращения к mm, vC, nmods были бы не к глобальным исходным массивам, а к локальным копиям. Вероятно проще все указатели убрать в регистры и правильно их инициализировать в начале.
2. В конце Iterate() перед меткой .next надо проверить .my_n и если больше 1 (или RCX==2 прямо перед call), то вместо рекурсивного вызова Iterate() сделать кучу других действий:
2.1. Увеличить счётчик запущенных потоков.
2.2. Запустить новый поток, передав ему его номер, в котором запустить новую функцию скажем IterateTh(). Где-то сохранить handle потока для п.2.3.
2.2.1. В этой функции скопировать локально нулевой и первый элементы mm (размером 172*128), остаток mm и весь vC и весь nmods обнулить (разумеется локальные копии).
2.2.2. Вызвать Iterate() с локальными mm, vC, nmods.
2.2.3. Атомарно (например через критическую секцию) добавить локальные vC и nmods к глобальным. Как обработать mm пока не знаю, надо вспоминать что это и зачем.
2.2.4. Выйти.
2.3. Чуть ниже метки .next, после jnz .cycle, ждать завершения всех запущенных потоков (функцией WinAPI WaitForMultipleObjects).
3. Из Iterate() убрать код показа прогресса в начале. В многопоточной среде вызовы WinAPI wsprintf и WriteFile глючат. Сделать нормальный прогресс можно, но это ещё столько же изменений кода как всё выше. Либо сделать очень грубый показ прогресса, только в одном потоке, с наименьшим номером (он дольше всех работает), это несложно.

Вот как-то так. Кажется это самый простой способ. И мне он не очень нравится.
Не факт что после этого будет работать, что-то сомневаюсь что можно mm сделать локальным, надо разбираться зачем он.
И не факт что ничего не забыл.
Разумеется по хорошему ещё надо добавить обработку разных аварийных ситуаций (например поток не запустился или не завершился).

Да, в таком варианте запустится много потоков, сколько может быть однократных загрязнений, но обычно это сильно больше 12, так что потоки будут конкурировать за время CPU, с этим ОС более-менее нормально справляется, ограничить количество потоков тут непросто (можно перед запуском очередного потока ждать пока количество запущенных не снизится до N-1 и только тогда запускать очередной, для этого в п.2.2.4 перед выходом атомарно уменьшать счётчик запущенных потоков и убрать его handle из списка из п.2.2).

Я очень сильно сомневаюсь что всё это (или лучше) может сделать ИИ.

-- добавлено через 23 минуты --

Для проверки "понимания" ИИ кода программы задайте ему простой вопрос: какие массивы меняются в Iterate(). Я прямо по коду вижу что mm, vC, nmods. Если он ответит меньше, то это facepalm - потому что это базовое понятие, что придётся делать локальным и потом как-то объединять от разных потоков в глобальные.

-- добавлено через 6 минут --

Кстати при неаккуратной реализации, например не дублировать массивы локально, а атомарно менять сразу глобальные, как вполне может предложить ИИ, работать многопоточно будет медленнее! Потому что массивы меняются очень часто и всё время будут занимать вызовы WinAPI для атомарного изменения.

 Re: Как писать быстрые программы
Аватара пользователя
Dmitriy40 в сообщении #1727673 писал(а):
Я очень сильно сомневаюсь что всё это (или лучше) может сделать ИИ.

Ну чё, попытка не пытка.

Бились мы с ним бились, я его наставлял внимательно перечитывать ваши инструкции. Прогресс полностью отключили. Бинарник получался жутко огромный — под 600МБ.

Диаметры 60 и 90 стали считаться быстрее, 90-й — 1.0 сек вместо 1.4. Но на диаметре 120 получилось примерно то же самое старое время в районе 135 секунд.

Вывод подсократил:

Код:
C:\FasmNew>HL1-16.exe 99 0 90
[929250773451000e0, 11103863001907200e0,
...
, 47393280e0]
Time: 0.986s

C:\FasmNew>HL1-16.exe 99 0 120
[1215599399289925650e2, 1842791168403046400e3,
...
, 123864586560e0]
Time: 134.486s

 Re: Как писать быстрые программы
Yadryara в сообщении #1727689 писал(а):
Бинарник получался жутко огромный — под 600МБ.
Вообще-то ни один из пунктов выше не предполагает заметного (более нескольких килобайт) увеличение exe файла ... Если только не переобъявить все массивы (включая и новые локальные) статически выделенными (dq вместо rq), но это ненужный бред. А локальные вообще в стеке потока (новой функции) вполне себе помещаются, их и объявлять не надо, как и заморачиваться с выделением памяти из кучи (heap).

 Re: Как писать быстрые программы
Аватара пользователя
Ну после этого он уменьшил до 40 мегов. И время для диаметра 120 упало до 125 секунд, но это за счёт не вывода прогресса.

А в новой сессии размер уже привычный — 73 КБ. И время для диаметра 120 — 125 секунд.

Ещё вот такой забавный результат у него получился:

Код:
C:\FasmNew>HL1-21.exe 99 0 60
[572556600e0, 4908898560e0]
Time: 0.017s
C:\FasmNew>HL1-21.exe 99 0 90
[929250773451000e0, 11103863001907200e0]
Time: 0.017s
C:\FasmNew>HL1-21.exe 99 0 120
[1215599399289925632e2, 1842791168403046400e3]
Time: 0.016s

То бишь числа верные, но показывает только первые два. Исправить он не смог.

 Re: Как писать быстрые программы
Ну так это эквивалентно ограничению рекурсии/загрязнения до 1:
Код:
>hl1-vc-time.exe 1 0 120
[1215599399289925650e2, 1842791168403046400e3]
Time: 0.001s
Молодец ИИ, чо.
И числа кстати не совсем верные, первое с погрешностью, хоть и очень небольшой (пока).

 Re: Как писать быстрые программы
Аватара пользователя
Dmitriy40 в сообщении #1727698 писал(а):
Ну так это эквивалентно ограничению рекурсии/загрязнения до 1:

Он вроде бы это понял и неоднократно пытался исправить, но в итоге сдался. Понятно что если я попрошу (или открою новый чат), он будет пытаться снова и снова. Но где-то же надо остановиться.

 Re: Как писать быстрые программы
Аватара пользователя
wrest в сообщении #1727710 писал(а):
По нему Qwen написал мне на Си программу, которая на arm64 планшете вычисляет константы для 0 90 за 40 секунд в однотопотке.

Надеюсь вы видели здесь в теме, что в однопотоке программа Дмитрия вычисляет числа для [0, 90] за 1 секунду на моём компе.

Но всё равно, спасибо, интересно. Я вот ещё думаю дочитать тему и вспомнить свой алгоритм, который позволяет считать некоторые паттерны почти вдвое быстрее. И попробовать всё-таки ускорить программу Дмитрия.

Насколько помню, CPAP-ы как раз из таких паттернов.

 Re: Как писать быстрые программы
Yadryara в сообщении #1727717 писал(а):
Надеюсь вы видели здесь в теме, что в однопотоке программа Дмитрия вычисляет числа для [0, 90] за 1 секунду на моём компе.

Да. Но ваш комп имеет термопакет что-то около 150 ватт, если я правильно помню. Или какой? А у планшета в лучшем случае 15. Больше кэш, больше ширина, больше частота, возможно - быстрее память. Так что 40х отставание на подобной очень специфической задаче -- это не так и плохо ;)

 [ Сообщений: 1405 ]  На страницу Пред.  1 ... 87, 88, 89, 90, 91, 92, 93, 94  След.


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