Обновить
7
0
Дмитрий Гах@dgakh

Разработчик ПО

Отправить сообщение
Благодарю за поддержку. Видимо с этой статьёй я просто не попал в тренд.
Большое спасибо за положительный отзыв. Вы правы — она собственно и ориентирована на программистов-самоучек. Ибо если программист сам не захочет учиться, насильно из него можно сделать только оператора.
Откровенно говоря я её начал писать давно и опубликовал по принципу что лучше пусть опубликую как есть чем будет валяться в ожидании доведения до совершенства. Тем более хорошая критика укажет явные промахи. Буду ломать мозги чтобы выбросить из неё лишнее и описать кое что яснее чтобы она была понятнее и полезнее большему числу читателей. :-)
Большое спасибо за Ваш детальный комментарий. Мне действительно приходится работать со студентами и хотелось найти ответы на некоторые вопросы. Я не ожидал множества положительных оценок за эту статью и хотелось больше вопросов и критики. Спасибо Вам за уважение к моему труду — Вы не просто поставили минус, но дали довольно объёмный отзыв! Я завтра пересмотрю статью с учётом Ваших комментариев. Ещё раз спасибо!
Речь идёт о языках программирования. Т.о. подразумеваются средства языков программирования и стандартных библиотек, предназначенные для реализации параллельного выполнения команд. Т.е. потоки, средства синхронизации потоков, распределение ресурсов и т.п.

Я заменил «Поддержка многозадачности.» на «Многозадачность.» для большей ясности.
Мне так повезло, что на C# приходится решать многие задачи, для решения которых лучше бы подошел С++. Что мне очень нравится, что в C# уровень можно выбирать в широких пределах. Если надо заоптимизировать — можно глубоко залезть, даже до unsafe. А если надо еще глубже — пожалуйста, можно часть кода написать на нативном С++ и подключить как unmanaged DLL.

Касательно Rust — очень интересный подход в его развитии.
То есть чтобы сделать и быстро, и красиво, нужно сначала очень напряженно подумать
. — уже тут зарыто много труда (чтобы упростить работу железа).

Кстати и на С++ так можно написать, что медленнее старого бейсика пойдет. Если не ошибаюсь даже просто с new/delete код на С++ можно сделать в разы медленнее чем на C#. И говнистость кода — вещь относительная. Иногда код — как бомж некрасивый, но свое дело делает четко (конечно лучше его привести и к хорошему виду). Эти вопросы наверное надо рассматривать с позиций менеджмента и дизайна.

За инфу о лекциях Андрея спасибо. Смотрю как раз запись. Тематика интересная.
Тут и кроется неудобство. Лучший дизайн может требовать рассмотрение структуры включая все поля, как одно целое. Алгоритм же в одной части может использовать 2-3 поля, в другой части другие поля. Выделить эти 2-3 поля в отделбную структуру а остальные в другую? Т.о. получим промежуточный вариант. Если так идти далее -придем к делению на примитивные данные. Деление — это уже не дизайн, а оптимизация.

Т.е. два конца палки — что упрощает работу программиста — усложняет работу железа. Лучшая практика — это для большинства случаев. Ведь си-шарп не системный язык и действительно надо делать структуры неизменяемыми. Это когда начинаешь. А деление на примитивы — частный случай оптимизации когда переписывать на С++ трудоемко, менять железо — ресурсоемко. Оптимизация, это когда логически уже работает и надо не создать, а улучшить для лучшего переваривания железом.
Да — 1000 полей — явный кейс. Или когда полей штук 20, берем 2,, а в массиве несколько десятков миллионов записей, Плюс вероятность доступа к соседним элементам высока.
Расходы памяти в этом случае — нулевые. А вот расход времени доступа увеличивается. Вопрос возникает когда чего-то начинает резко не хватать. Вот тогда и решаем чем жертвовать. Если же место есть и процессор не перегружается — можно и не думать об оптимизации.
В примере структура короткая. Если алгоритм оперирует только частью полей (на оопределенном участке), разделение дает преимущество в особенности для длинных структур и при доступе, где вероятность работы с соседними значениями велика. Например даже если рандомно обращаться только к одному или нескольким полям при их разносе в массивы вероятность обращения к физически соседним полезным данным выше (я не имею в виду расстояние, но то, позволит ли оно например вместиться в кеш). Различия могут быть как заметными так их может и не быть — зависит от алгоритма.

В Вашем случае будет явное преимущество при не-разбиении если нужна вся структура целиком и поля в ней «хорошо» выровнены.
Про векторизацию помнил, но уже капнуть глубже просто не успел. Тут тоже как понимаю возникают варианты и в каждом случае мы можем получить тот или иной эффект. Но для более простых процессоров эффект от замены должен быть ощутимей.
Да, думаю не всегда. Но и не редко. Думаю вопрос требует систематизации. Чтобы уже точно знать от чего чего ожидать. У меня пока на руках теория + один узкий показательный пример.
Ок. Мне самому интересно. Пока я вижу только выигрыш, так как он полностью соответствует теории. Т.е. если я только лишь улучшаю структуру данных и после этого имею выигрыш при каждом запуске, это скорее всего наведёт на мысль о взаимосвязи, ведь погрешность бы скакала и отрицательные значения компенсировали бы время в случае если ничего не улучшилось.

Но все-же более интересен другой вопрос. Если дело идет о широком использовании, надо тестировать точнее, увереннее и на разных платформах. А то уверенность что тут я выиграл не дает гарантии что на другой платформе или алгоритме не будет проигрыша. Т.е. более понять вклад в цифру разных факторов.
Алгоритм Поиска Пути. Тест простой — разница во времени между началом и концом вычислений для одинаковых путей. Т.е. 0.6% — не только время доступа, но и другие внутренние операции. Цифра грязная, но соответствует только одному изменению — разбиению на массивы полей.

Железо — Intel i7, 4 Gb RAM. Но тестировал в режиме x86 ( 32 бита ). Тестировал много раз, так как долго отлаживал.

Не являются ли постоянные малые положительные показания доказательством хотя бы малого, но положительного эффекта? Может я зацикливаюсь и что-то не учел?
Я немного подкорректировал статью. В С++ данный аргумент как-то не смотрится практичным. С другой стороны при его написании я подразумевал C#. Теперь ошибку исправил: «При разработке в C# там где это возможно, нужно использовать структуры, а не классы».
Если в определенном месте алгоритма, например каком-то цикле нужна только часть полей структуры, а не она вся, массив тут оптимальнее. Но выигрыш тут правда небольшой — у меня на С++ в релизе с оптимизацией на скорость выигрыш составил порядка 0.6% по времени. Но разбиение конечно усложняет код и это серьезный аргумент в пользу структур. Дело случая.
А так, — я как-то стараюсь создавать структуры с полями в 32 байта — не сильно напрягает, но упаковка лучше.
Железо. В общих словах — обращение к данным, не находящимся по кратным разрядности адресам требует дополнительных операций процессора.
Да, читал. У меня в ссылках есть. И в комментариях много интересного. Тут как говорится по задаче надо лучший метод выбирать.
Тут вопрос доступа к структурам в массиве и к полям в массиве. Т.е. и там и там массив.

Откровенно говоря меня иногда С# бесит, особенно когда нужно байтокамасутрится :-) В особенности отсутствие битового представления числа… Тут уж как говорится если требуется так, то уже… Просто на вопрос — куда в C# деваются 73% памяти на 64 битной системе без заглядывания вовнутрь не обойтись.

Но история началась с части кода на С++, после изменения которого возникла нехватка памяти. Вот и пошло по цепочке. Отоптимизировал код на С++ по полной ( даже кажется это уже чистый С получился ). Потом залез в C# глазами С++ — ника. И напоролся на такое обжорство…
В выравнивании и экономии памяти поможет. Но скорость доступа будет меньше чем при разбиении на массивы полей. И если не ошибаюсь меньше и при доступе к полям структуры — ведь их выравнивают для оптимизации доступа.
1

Информация

В рейтинге
Не участвует
Откуда
Баку, Азербайджан, Азербайджан
Зарегистрирован
Активность