А был ли мальчик? (помянем плюсы)

User avatar
Prosche
Уже с Приветом
Posts: 8090
Joined: 08 Nov 2004 12:24
Location: GA

Re: А был ли мальчик? (помянем плюсы)

Post by Prosche »

И не говорите. Я вот все больше убеждаюсь, что у людей отсутствует элементарный каммон сенс, пытаются рассуждать о высоких материях, не понимая элементарного. Огромное число диванных теоретиков в любой области. А ты потом, после них, смотришь на код и пытаешься вкурить, почему передвинув маленький массив из а на место огромного в б, последний обнаруживается в а. Теперь вот буду знать, поработали спасатели "дорогих ресурсов" :)
User avatar
AndreyT
Уже с Приветом
Posts: 3003
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Re: А был ли мальчик? (помянем плюсы)

Post by AndreyT »

Prosche wrote: 25 Jan 2018 17:21 Огромное число диванных теоретиков в любой области. А ты потом, после них, смотришь на код и пытаешься вкурить, почему передвинув маленький массив из а на место огромного в б, последний обнаруживается в а.
О, это целый пласт!

Сразу приходит в голову такой популярный вопрос на Интернете у разработчиков of Bangalor persuasion. Типа: "Я уничтожил свой массив через `delete[]`, а потом заглянул в якобы "уничтоженную" память через этот же указатель, а мои данные там все лежат нетронутые. Как так? Почему? Я же сказал - "уничтожить", а они все равно там!" (Вариации: возвращение указателя на локальный объект и т.д. и т.п. Отдельный плюс: ссылка на значение слова `delete` в Оксфордском словаре. )

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

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

Вот, я смотрю, и у вас что-то наблюдается нестерпимое желание совать в свой нос в недра moved from объекта и разглядывать то, что в нем "обнаруживается"... И понять тот факт, что в рамках move semantics это вас вообще не касается и интересовать совершенно не должно, вам похоже, пока не по силам...
Last edited by AndreyT on 25 Jan 2018 19:01, edited 2 times in total.
Best regards,
Андрей
User avatar
Prosche
Уже с Приветом
Posts: 8090
Joined: 08 Nov 2004 12:24
Location: GA

Re: А был ли мальчик? (помянем плюсы)

Post by Prosche »

когда у вас массив на пару гигов, который вы заменили другим, как вы считаете, на самом деле никуда не денется, а продолжит отжирать память, то вы очень быстро и "под капот" залезете, и все детали имплементации узнаете, и еще и толстый пучок диарейных лучей в направлении автора пошлете.
User avatar
Medium-rare
Уже с Приветом
Posts: 9195
Joined: 04 Mar 2011 03:04
Location: SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Medium-rare »

AndreyT wrote: 23 Jan 2018 19:32 Во-первых, львиная часть идеи шаблонного программирования как раз и заключается в том, что шаблонный класс может содержать операции, неприменимые для некоторых типов шаблонного аргумента, но это нам никак не должно мешать, пока мы не пытаемся эти операции использовать (инстанциировать).
Ну, на практике, когда пользователь моего компонента не может применить стандартную операцию над контейнером данных, полученных от него, можно, конечно, объяснить, что ему необязательно ожидать наличие такой операции в данном конкретном случае. Но обычно они продолжают возмущаться. :)
Во-вторых, ожидание доступности всех операций контейнера - это некий С++98-стиль мышления. В С++98 первичен был сам контейнер: доминировали жесткие требования контейнера, а элемент вынужден был волей-неволей под них подстраиваться, даже если это больше нигде никому не было нужно. И это, вообще-то, плохо, ибо с точки зрения здравого смысла должно быть как раз таки наоборот - свойства элемента контейнера должны быть первичны. И они должны прозрачно проноситься (форвардиться) сквозь контейнер в окружающий мир, также как это работает с "рукописными" голыми массивами, списками и т.п.
Duly noted. Так и буду отпинывать недовольных моими контейнерами.
Причем в С++98 такое жесткое доминирование правил контейнера сделали отнюдь не потому что это считалось "правильным", а просто потому, что в языке не было адекватных средств для того, чтобы сделать по-другому. Это стало возможно только в С++11. Но даже и в С++98 допустимые операции над контейнером зависели от определенных свойств элемента, хотя бы на интерфейсном уровне - например, возможность или возможность конструкции по умолчанию для элемента влияла на большое количество возможностей вызова методов контейнера.
static_assert почаще применять для устранения недопониманий... Как в свой код поставить, понятно. А если хочется внятно сообщить о неправильном случае использования стандартного контейнера для конкретного типа?
... and even then it's rare that you'll be going there...
User avatar
AndreyT
Уже с Приветом
Posts: 3003
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Re: А был ли мальчик? (помянем плюсы)

Post by AndreyT »

Prosche wrote: 25 Jan 2018 18:05 когда у вас массив на пару гигов, который вы заменили другим, как вы считаете, на самом деле никуда не денется, а продолжит отжирать память, то вы очень быстро и "под капот" залезете, и все детали имплементации узнаете, и еще и толстый пучок диарейных лучей в направлении автора пошлете.
Мне надоело рассказывать "сказку про белого бычка" снова и снова.

Всем прекрасно понятно, что в "среднестатистических" приложениях в 99 случаях из 100 move делается из expiring объекта. То есть moved from объект будет уничтожен практически сразу после того, как из него сделали move. В такой ситуации разница во времени жизни ресурсов в любой реализации move будет сводиться к жалкому десятку тактов процессора. Мove-присваивание, реализованное через swap, тоже с радостью освободит вашу "пару гигов" при деструкции правой части. Так что не надо пугать людей: никто не будет "продолжать отжирать память".

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

На такие вопросы не существует ответа вне конкретных контекстов.

И даже в тех ситуациях, когда эти "пару гигов" действительно никому не нужны, вопрос на самом деле уже впрямую и не относится к move semantics. Это на самом деле та же извечная проблема как, например, в `std::vector`, который исторически накопил capacity в ваши "два гига", но сейчас имеет size в какие-то жалкие три байта. Что делать? Может вызывать shrink_to_fit? А может погодить - вдруг сейчас "два гига" таки сразу понадобятся?

Повторюсь: на такие вопросы не существует ответа вне конкретных контекстов.
Best regards,
Андрей
User avatar
Prosche
Уже с Приветом
Posts: 8090
Joined: 08 Nov 2004 12:24
Location: GA

Re: А был ли мальчик? (помянем плюсы)

Post by Prosche »

AndreyT wrote: 25 Jan 2018 18:57 В тех же ситуациях, когда правая часть продолжает долго жить и после move, этот вопрос уже переходит в совсем другую плоскость. Раз он продолжает долго жить, то значит он кому-то нужен? Может быть это и хорошо, что он продолжает отжирать "пару гигов"? Может в него сейчас эти самые "пару гигов" и захотят записать, а он как раз к этому готов?

На такие вопросы не существует ответа вне конкретных контекстов.
Повторюсь: на такие вопросы не существует ответа вне конкретных контекстов.
Вы начинаете повторяться.
Ответ безусловно существует. И он тривиален. В таком случае надо использовать свап. И мув тут совершенно не при делах.
User avatar
AndreyT
Уже с Приветом
Posts: 3003
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Re: А был ли мальчик? (помянем плюсы)

Post by AndreyT »

Prosche wrote: 25 Jan 2018 19:09 Ответ безусловно существует. И он тривиален. В таком случае надо использовать свап. И мув тут совершенно не при делах.
Move semantics для класса в С++ - это не более чем набор special member sunctions (move constructor и move assignment operator), которые служат в качестве интерфейса между рукописным кодом и ядром языка. А также простое "джентельменское соглашение": левая часть должна получить значение правой части, а правая часть должна получить некоторое неспецифицированное, но валидное состояние. Никаких других "надо" или "не надо" тут нет.

Классическая copy semantics является примером move semantics. Swap semantics тоже является примером move semantics. Можно придумать еще множество разнообразных примеров move semantics. С чего вы взяли, что ваши верования являются Единственным Истинным Способом реализации move semantics мне в упор не ясно.
Best regards,
Андрей
Pantigalt
Уже с Приветом
Posts: 803
Joined: 24 Jan 2007 07:32
Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Pantigalt »

ksi wrote: 25 Jan 2018 05:37 А можно unrelated вопрос? У меня была такая ситуация (я не программист в чистом виде, поэтому сорри, если чего не понимаю): мне нужно создать в памяти копии какого объекта. В большом количестве, сотни тысяч или миллионы потенциально. Поинтеры на новые объекты куда-то положить, ну в массив например. Есть какой-нибудь трюк чтобы это сделать наиболее быстро или ничего кроме цикла из memcpy нельзя придумать? И второй вопрос - а можно это как-то multithreaded или memory manager все равно не способен параллельно выделять память? Или нужен специальный memory manager, которые могут это поддержать? Такие есть?
Если реально столько много их то можно было бы подумать не о куче а о глобальной памяти.
Если вы знаете верхний предел то можно выделить сразу большой кусок.
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
Pantigalt
Уже с Приветом
Posts: 803
Joined: 24 Jan 2007 07:32
Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Pantigalt »

ksi wrote: 25 Jan 2018 06:16 Ну произвольная структура какая-то, инстанс какого-то класса. Нважно С или С++. Такая задача, неважно откуда она возникает, это специфическое применения. Потом эти копии будут модифицироваться, слега, ну какое-то поле будет подправлено. Мой опыт, что модификация занимает в сотни раз меньше времени, чем отведение памяти под объект, поэтому и вопрос. Надо сэкономить на копировании.
У вас классическая задача COW - copy on write. Погуглите на эту тему.
Насколько я помню Windows это вовсю использует для работы с памятью.
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
User avatar
AndreyT
Уже с Приветом
Posts: 3003
Joined: 14 Apr 2004 01:11
Location: SFBA (было: Минск, Беларусь)

Re: А был ли мальчик? (помянем плюсы)

Post by AndreyT »

ksi wrote: 25 Jan 2018 05:37 А можно unrelated вопрос? У меня была такая ситуация (я не программист в чистом виде, поэтому сорри, если чего не понимаю): мне нужно создать в памяти копии какого объекта. В большом количестве, сотни тысяч или миллионы потенциально. Поинтеры на новые объекты куда-то положить, ну в массив например. Есть какой-нибудь трюк чтобы это сделать наиболее быстро или ничего кроме цикла из memcpy нельзя придумать?
Если погрузиться глубже уровня С++ платформы, то в системах с виртуальной памятью вы можете достичь такого эффекта заполнив копиями вашего объекта всего одну физическую страницу памяти и замапив эту единственную страницу в требуемый вам диапазон виртуальных адресов адресного пространства процесса. То есть пока вы используете этот диапазон адресов только по чтению, вы будете видеть в нем виртуальные копии одной и той же физической страницы: гигантский массив копий, на построение которого вы затратили минимальные усилия.

При необходимости записи будет работать механизм copy-on-write, т.е. при записи в некую точку этого диапазона виртуальных адресов от исходной физической страницы "на лету" будет отпочковываться новая физическая страница, в которой и будет выполняться модификация. Понятно, что если в конечном итоге вы собираетесь модифицуировать все элементы вашего гигантского массива, то "отпочкуется" в итоге все: финальный эффект не будет отличаться от изначального физического выделения и явного заполнения всего массива...
Best regards,
Андрей
Pantigalt
Уже с Приветом
Posts: 803
Joined: 24 Jan 2007 07:32
Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Pantigalt »

ksi wrote: 25 Jan 2018 14:17 А память под вектор выделяется одним куском или она может быть фрагментирована? Это можно как-то эмулировать в С стиле: я имею в виду, что если просто звать malloc (1000000*sizeof (MyObject)) то такого куска памяти подряд может просто не быть. У вектора есть внутренняя поддержка для таких ситуаций?
На этот случай есть std::deque.
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
Pantigalt
Уже с Приветом
Posts: 803
Joined: 24 Jan 2007 07:32
Location: Сергели->Новосибирск->SFBA->Новосибирск->Москва->NY->SFBA

Re: А был ли мальчик? (помянем плюсы)

Post by Pantigalt »

del
Спи быстрее, твоя подушка нужна другому. Copyright Зощенко
Сабина
Уже с Приветом
Posts: 19041
Joined: 11 Jan 2012 09:25
Location: CA

Re: А был ли мальчик? (помянем плюсы)

Post by Сабина »

Prosche wrote: 25 Jan 2018 16:08 Хорошо, хотите натягивать мув на свап, не смею вам мешать. Я сделал все что мог.
Хотите думать, что мув придуман чтобы сохранять дорогие ресурсы, барабан вам на шею. Будете сидеть в тишине вашего кабинета, попробуйте подумать почему именно мув, такое странное название, в словарик там посмотрите. Может быть осознаете простую истину, что идея мув в мув, взять справа и передвинуть влево, а совсем не сохранить "дорогие ресурсы".
То есть вы не просто "страшный", вы еще и спорить любите :mrgreen: ?
https://www.youtube.com/watch?v=wOwblaKmyVw

Return to “Вопросы и новости IT”