All streams
Search
Write a publication
Pull to refresh
61
0
Павел @Hemml

астрофизик

Send message

А смысл? Показать людям, как выглядит код на турбопаскале? Это была просто игрушка, которой я баловался на первом курсе и не довел до ума. Сейчас можно уже реализовать эту идею более серьезно и что-то выложить, но лично я не готов этим заниматься. Скажем так, я избрал другую ветку развития)

Помнится, в школе, на уроке литературы учительница меня вызвала к доске и попросила пересказать сюжет "Обломова". Произведение это я к тому времени прочитал до половины и надеялся, что рассказав начало, буду отпущен с миром и дальше пойдет рассказывать кто-то другой. И вот, приближаясь к границе своих познаний, я начинаю тянуть время -- вдаюсь в подробности, делаю краткие отступления и пояснения, в общем, жгу глаголом, как могу. Это сыграло со мной злую шутку -- учительница явно заслушалась и мне пришлось пересечь рубеж, за которым начиналась область догадок. В общем, я попытался угадать развитие сюжета. Увы, неудачно :(

Как работает человеческий мозг -- тайна великая есть. Пока что даже работу отдельного нейрона не удается достоверно промоделировать, насколько мне известно. Утверждать, что мозг и компьютерная нейросеть работают на одной принципе, преждевременно, как мне кажется. Но я не специалист и могу ошибаться.

Вообще-то в посте, на который я ссылаюсь, перечислены скверные вещи, которые могут произойти в будущем, я добавил к ним еще одну. Что касается вашего вопроса, не совсем про нейросети, но навигаторы уже практически лишили нас способности ориентироваться в незнакомой местности, например. Через некоторое время человечество не сможет надевать штаны без помощи нейросети, запросто.

Ох. Я этот проект мысленно похоронил более чем 25 лет назад. Чтобы написать статью, мне надо его оживить, заставить работать, поисследовать и погонять на разных данных. Это долго. К тому же я не владею матчастью, скорее всего этот подход известен и как-то называется, где-то защищались диссертации, проходили симпозиумы, и тут я вылезаю с программой на паскале и текстом про женщин времен фидо)

Проблема не в невозможности прожить без знания о том, как запрягать лошадь, проблема в "магическом мышлении", когда какие-то вещи считаются "сами собой работающими" и о их устройстве человек не подозревает. Ребенок должен знать, что лошадь, в принципе, запрягают, зачем это делают, как изобретение упряжи повлияло на развитие цивилизации. Это базис, основа. Это поможет ему понять многие другие вещи. Так же как умение считать в столбик поможет ему более глубоко понимать суть систем счисления, например. Может быть прямо это ему не пригодится, но пригодится знание подхода, понимание, что калькулятор делает примерно то же самое, что в нем нет никакой магии.

У меня есть знакомый, дочь которого живет в Канаде и у него там родился внук. Внуку примерно лет 10. Когда дедушка приехал его навестить, он предложил разжечь костер на заднем дворе и пожарить сосиски. Внука очень удивило и впечатлило, что огонь, оказывается, можно разжечь. Он в принципе не подозревал, что так можно.

Это вряд ли. К тому же там нейросеть совсем не классическая, никакого там back propagation и прочих сложностей. Простая, как палка -- каждое слово -- нейрон, если встретилось в тексте -- добавляем ему энергии, между двумя самыми возбужденными устанавливаем (усиливаем) связь. Над всем этим стоит система усиления-торможения, которая на каждом шагу увеличивает возбуждение самого возбужденного нейрона и притормаживает все остальные. Функция возбуждения нейрона из книжки по M-автоматам (кажется). Не уверен, что она сможет побить ChatGPT.

Нашел! Там даже какая-то документация есть и файлы, на которых я ее обучал (не ржите). Кодировка CP866.

Отличный аргумент, слышал его много лет назад) А вы никогда не задумывались, зачем детей в школах учат писать от руки и считать без калькулятора? Ведь, казалось бы. Может быть они дальше уже никогда не будут этого делать, но они должны понимать принцип, чтобы сложение двух чисел не казалось им магией. Дети с этим не согласны, конечно.

У меня где-то есть образ HDD от моего компьютера тех времен (сам HDD тоже есть, но его уже некуда подключать), вполне возможно, код там сохранился. Это была программа на Turbo Pascal и она была ужасна, разумеется)

Отличная статья, но в ней не описан один момент, связанный с синхронными XHR. Я знаю, что они obsleted, но иногда без них нельзя обойтись. Так вот, в процессе ожидания данных от xhr, браузер вполне может выполнять другой код. Например, если в это время придет сообщение через вебсокет, то обработчик будет вызван, не дожидаясь, пока отработает задача, висящая в ожидании xhr. По крайней мере, в FF. Когда пишешь на JS, внутренне полагаешься на то, что код строго однопоточный, но, как миниумум функции, где есть синхронные xhr, надо рассчитывать на реентерабельность.

Когда-то давно я видел даже библиотечку, которая реализовывала кооперативную многозадачность через внутренние xhr :)

У меня создается впечатление, что вы на меня за что-то сердитесь. Совершенно напрасно. Очень хорошо, что вы выучили систему типов в языке C и (тут повторюсь) это действительно вам пригодится в будущем. Давайте вернемся к началу нашей беседы. Я утверждал, что все попытки аспирантов переписать код с фортрана на C, которые я наблюдал, кончались неудачей -- они получали код, работающий существенно медленнее и, практически всегда, выдающий неправильные результаты. Особенности языка этому способствуют. При этом я даже не считаю, что это плохо, аспирант тратит кучу времени, но лучше узнает устройство кода, повторяет численные методы и, в итоге, начинает больше ценить фортран, одни плюсы. При этом у меня и в мыслях не было как-то унижать C, это хороший язык, пусть и предназначенный для других вещей. У меня коллега написал код не просто на С, а даже на C++ и это хороший код. Работает он, правда, все равно медленнее фортрановского, но их нельзя так прямо сравнивать, внутри они сильно отличаются. Так что и на C можно написать код, но возможностей выстрелить себе в ногу там неизмеримо больше, чем в фортране, да и сам он менее удобен для этой цели.

Вообще, я давно перерос все эти споры в стиле "X" круче "Y", перерастете и вы :)

Скорее всего этого не было в справочнике. А не было, вероятно, потому, что это либо не поддерживалось в компиляторах, либо поддерживалось, но не работало как должно было)

Нет, язык не тот же, несмотря на схожесть названий) В момент, когда ANSI решили придумать свой стандарт, язык C уже уществовал лет 20. Поскольку ANSI C был несовместим с C (на C уже было много чего написано, в том числе UNIX), а также, подозреваю, по причине нелюбви разработчиков к бюрократам из ANSI, стандарт очень долго существовал "на бумаге", но мало кем поддерживался и использовался. Потом всё изменилось, конечно, Linux пришел на смену UNIX, а в разработку пришло много вчерашних студентов, изучавших программирование на курсах, так что ANSI всё же стал использоваться.

С89, это же ANSI C, тот самый стандарт, который много лет никто не хотел поддерживать? Ну, тогда понятно. Мы просто говорим о разных языках, хотя они, по недоразумению, называются одинаково)

Хм. То есть одна и та же конструкция x[1][2][3] теперь в C может работать совершенно по-разному? Хотя выглядит одинаково? И это уже даже вошло в стандарт? Лол.

Возвращаясь к теме поста -- вот как раз пример того, как умирают языки. В попытке догнать Фортран (еще раз лол) ребята придумали новый язык, похожий внешне на C, но программы в нем теперь работают по-другому. По странному недоразумению они тоже назвали его C. Молодцы, что уж тут. Почему было не использовать сразу Фортран?

Зачем такие сложности? Вот более простой пример, полностью соответствующий стандарту:

void test(char ***x) {
  x[5][5][5]=100;
}

Не в курсе, что такое godbolt, потому скомпилирую простым gcc:

$ gcc -c -save-temps test.c
$ ls
test.c	test.i	test.o	test.s

Содержимое test.s:

	.text
	.globl _test
_test:
LFB0:
	pushq	%rbp
LCFI0:
	movq	%rsp, %rbp
LCFI1:
	movq	%rdi, -8(%rbp)
	movq	-8(%rbp), %rax
	addq	$40, %rax
	movq	(%rax), %rax
	addq	$40, %rax
	movq	(%rax), %rax
	addq	$5, %rax
	movb	$100, (%rax)
	nop
	popq	%rbp
LCFI2:
	ret
LFE0:
	.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
EH_frame1:
	.set L$set$0,LECIE1-LSCIE1
	.long L$set$0
LSCIE1:
	.long	0
	.byte	0x1
	.ascii "zR\0"
	.byte	0x1
	.byte	0x78
	.byte	0x10
	.byte	0x1
	.byte	0x10
	.byte	0xc
	.byte	0x7
	.byte	0x8
	.byte	0x90
	.byte	0x1
	.align 3
LECIE1:
LSFDE1:
	.set L$set$1,LEFDE1-LASFDE1
	.long L$set$1
LASFDE1:
	.long	LASFDE1-EH_frame1
	.quad	LFB0-.
	.set L$set$2,LFE0-LFB0
	.quad L$set$2
	.byte	0
	.byte	0x4
	.set L$set$3,LCFI0-LFB0
	.long L$set$3
	.byte	0xe
	.byte	0x10
	.byte	0x86
	.byte	0x2
	.byte	0x4
	.set L$set$4,LCFI1-LCFI0
	.long L$set$4
	.byte	0xd
	.byte	0x6
	.byte	0x4
	.set L$set$5,LCFI2-LCFI1
	.long L$set$5
	.byte	0xc
	.byte	0x7
	.byte	0x8
	.align 3
LEFDE1:
	.ident	"GCC: (MacPorts gcc8 8.4.0_0) 8.4.0"
	.subsections_via_symbols

Давайте вместе подсчитаем обращения к памяти?

Изначально мое утверждение было -- фортрановские массивы быстрее, чем массивы с C, так как требуют меньше обращений к памяти. Это так, по стандарту. Тут выходите вы и начинаете опровергать, приводя примеры. Я понимаю, как вы к этому пришли -- попробовали, о, доступ к массиву не через массив ссылок, а напрямую. Из этого вы сразу же делаете вывод о том, что в C массивы работают так всегда и начинаете защищать этот вывод опять же при помощи примеров.

Я тоже люблю экспериментировать, в этом мы с вами близки. Но у меня хватает жизненного опыта, чтобы не делать далеко идущих обобщений из частных случаев. Конкретно, в вашем случае, компилятор нарушает (ради оптимизации) канонический (описанный в стандарте) способ работы с массивами по двум причинам: 1) он точно знает размерность массива; 2) он точно знает, что с этим массивом не будет работать никакой внешний код. Внешний, в данном случае, не контроллируемый этим же компилятором. Тогда и только тогда работа с массивом будет происходить так, как вы предполагаете. Стоит одному из этих условий нарушиться и вы получите очень медленный код в лучшем случае. В худшем -- неопределенное поведение.

Когда K&R проектировали C, они сознательно пошли на такой способ работы с массивами. Это дает возможность определять адрес любого элемента, не зная размерности массива. Скорость, вероятно, для них не была приоритетом в то время. В принципе, массивы в фортрановском стиле в С реализовать можно и так, через макросы, например. В фортране же работа с многомерными массивами зашита прямо в язык и в нем с ними работать удобнее.

Upd: во времена создания C процессоры просто не имели многоуровневых кэшей и скорость доступа к массивам была, наверное, даже быстрее, чем в фортране, так как фортрану нужно подгрузить из памяти размерности, потом провести сложения и умножения, тогда как C достаточно было всего лишь подгрузить значения. Но в современных процессорах доступ к памяти стоит много дороже, чем в PDP11 и фортран выигрывает)

Вы с удивительным упорством пытаетесь доказать ошибочное утверждение, прибегая при этом к уловкам, не надо так. Давайте проведем чистый эксперимент: передача массива по ссылке, процедуры get/set_element не знают размерность массива. Чистый C.

Ну вот не надо передергивать. При чем тут sizeof? Как одинаковость или разность значений, возвращаемых sizeof, определяет тип переменной? Вы вообще в курсе, что такое типы? Справочник, кстати, был отличный, перевод канонического стандарта, кажется, K&R, но я не уверен. Чай, не википедия какая. И про типы там всё было хорошо написано.

Все ваши примеры отлично работают в пределах одного исходинка. Попробуйте передать ссылку на ваш "массив массивов" во внешнюю процедуру, определенную в прилинкованной библиотеке и посмотрите, как там будет осуществляться доступ. Hint: подумайте о том, как та процедура узнает о размерности массива, по одному указателю. А передача указателя -- легитимный способ сослаться на массив.

Ну и про типы почитайте что-нибудь, очень полезно, рекомендую.

Information

Rating
Does not participate
Location
Москва и Московская обл., Россия
Registered
Activity

Specialization

CFD-моделирование
Lisp
Fortran
C
LATEX
Applied math
Python
SQL
Docker