Re[34]: велосипеды vs boost и пр "стандартные" решения
От: remark Россия http://www.1024cores.net/
Дата: 27.08.07 20:38
Оценка:
Здравствуйте, Sergey, Вы писали:

S>И может быть даже удастся обойтись без мьютекса, одними CAS'ами.


Двухсвязанный список на CAS'ах построить достаточно не тривиально.
Алгоритмы в принципе есть. Вопрос — зачем.

На мьютексах будет быстрее. Единственный смысл делать — если нужна именно lock-free гарантия, для асинхронных обработчиков прерываний например.

Если уж отходить от мьютексов, то есть гораздо более интересные решения и гораздо более производительные и масштабируемые. Я имею в виде решения для управления временем жизни объектов.


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[14]: велосипеды vs boost и пр "стандартные" решения
От: Erop Россия  
Дата: 27.08.07 20:45
Оценка:
Здравствуйте, jazzer, Вы писали:

E>>1) Кто-то должен поддерживать актуальность требований на использование А, Б и В, и следить за их соблюдением

J>это необходимо в случае любой библиотеки, в том числе самописной.
Ну самописная библиотека может быть не такой всеобъемлющей, как буст

J>А у вас в конторе не так? Новая версия самописной или третьей библиотеки (не буста, свят,свят,свят!) просто инсталлируется и используется как есть?


Ну при смене версий конторских либ, те, кто меняют версию, меняют и всех клиентов (это какие-то внутриконторские пользователи библиотеки) соответсвующим образом. Потмо клиенты переходят на изменённую версию.

Когда меняется внешняя библиотека (но такие не бывают всеобъемлющими), то те, кто поддерживают использование этой библиотеки переносият её клиентив на новую версию.

J>Во-вторых, все доступно в исходниках — меняй, если что-то не нравится.

J>Причем это не GPL, так что ты не обязан сабмитить свои изменения куда-либо.
J>Например, мы спокойно поменяли пару вещей в буст.тест, потому что нас оно не вполне устраивало, и не испытываем по этому поводу никаких угрызений совести.

Ну так у нас тоже делали. Но потом эти изменения накапливаются и становится очень дорого поднимать верси исходнйо библиотеки

J>если заказчик пользуется бустом, то он обычно и говорит, какой именно версией он пользуется, и надо разрабатывать на этой версии.

J>если не пользуется — значит, надо ему отдавать библиотеки той версии, которую ты используешь.
J>Не вижу проблемы.

А если у тебя нет заказчика? Если коробочный продукт с большим числом пользователей?

J>И получается софт, который чудо как хорош по всем показателям, кроме затраханности персонала, о которой никто, кроме самого этого персонала, не знает. Конкретному примеру в следующем году 15 лет стукнет. С версиями, с поддержкой, со всеми пирогами.

ИМХО это явление социальное, а не программо-техническое... При желании задёшево затрахать персонал и внедрить потогонную систему никакой boost не помешает, как впрочем и не поможет

J>На юниксах это делается гораздо проще: открывается сегмент общей памяти и запускается процесс, который возьмет из него данные, сделает всю работу в своей личной куче, и результат сложит обратно в общую память, после чего помрет и свою кучу с собой прихватит.

J>И никакой возни с аллокаторами.
Ну это немного радикальная архитектура -- fork на каждый процесс. В конце коноцв это и на Windows можно, а вот на всяких "нетяжёлых" платформах затруднительно. Да и делать это ради ошибок, которых может и не будет, ИМХО, и не стоит.
Кроме того "критические ресурсы" это же не обязательно память. Это может быть временый файл, сетевое соединение, ещё что-нибудь во внешнем мире

E>>>>>>>>

J>Ну так о чем и речь. Когда язык начнет гарантировать, что данный код, помеченный данным атрибутом, защищен от любых оптимизаций (в том числе и встроенных в процессор) — тогда ы можешь гарантировать, что твой код абсолютно корректен. И для этого нужна именно поддержка со стороны языка.
Скорее всего ты сможешь гарантировта только исключительную тормознутость твоего кода

J>Ну должны быть в язке атомарные типы, ничего ты без них переносимо не сделаешь, котому что в винде это будет какой-нть InterlocetIncrement, а в gcc — atomic_t.


Ну это мелкая проблема. Хотя конкртено аналог InterlocetIncrement втандартизировать наверное можно.

J>ну так есть фьючерсы, есть work stealing, много идей вообще бродит на эту тему.

Ну так слишком их много. Стандартизировать наверное рано.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[14]: велосипеды vs boost и пр "стандартные" решения
От: Erop Россия  
Дата: 27.08.07 20:46
Оценка:
Здравствуйте, Alex Alexandrov, Вы писали:

AA>Впрочем, можно отверсионировать namespace — так мы тоже делаем

И мы, когда припирает
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[28]: велосипеды vs boost и пр "стандартные" решения
От: Left2 Украина  
Дата: 27.08.07 20:50
Оценка:
L>>Э... А что — часто приходится клепать аналоги std::sort или там std::partial_sort? Ну и в любом случае — функтор который в алгоритм передаётся абсолютно никак не обязан быть шаблоном. Или я недопонял чего-то?

E>Ну я тоже считаю, что STL-way, то есть такой способ программирования, когда можно в програме взять и заменить std::vector на std::list "если надо" -- не нужная на практике степень унификации. Но встречавшиеся мне любители связки STL + boost это дело постоянно рожают.

E>В конце концов STL -- это же не только набор шаблонов, но и набор соглашений о том, как нужно программировать контейнеры и алгоритмы, чтобы они были все совместимы между собой.
Во! Вот это типичная ошибка — считать что контейнеры STL должны быть заменяемы друг на друга лёгким движением руки ЕМНИП, Герб Саттер, которого я очень уважаю за то что он самый большой практик из всех гуру С++, предлагал забыть об этом принципе сразу и навсегда. ПисАть код который был бы контейнеро-независимым — слишком сложно и в итоге невыгодно экономически в большинстве случаев.

E>Но я бы на всяк. случай ещё посмотрел в сторону конкурентов. MFC там, PowerPlant и т. п.

MFC — отказать сразу ИМХО, абсолютно безыдейные там стандартные контейнеры. STL куда как прогрессивнее.
А PowerPlant — это http://sourceforge.net/projects/open-powerplant ? Первый раз слышу. Стоящая вещь? Есть смысл смотреть?
Re[16]: велосипеды vs boost и пр "стандартные" решения
От: Erop Россия  
Дата: 27.08.07 20:51
Оценка:
Здравствуйте, WolfHound, Вы писали:

E>>Очень аргументированно.

E>>Ответ -- не убедил
WH>См в архитектуре флеймы про синглетоны.
Ну и там не убедил

WH>>>Против констант заданных на этапе компиляции я ничего не имею.

E>>А если на этапе компиляции эти данные вычислить затруднительно?
WH>Например?
Например при их вычислении нужно вызывать какой-то код. Скажем из другой ещё библиотеки.
Или, например, тебе надо протабулировать косинус...

WH>Исключения нужно кидать всегда когда случается ошибка.

WH>Они для того и создавались.
Я согласен. Но у нас, во всяком случае, ошибка на каждый чих не случается
А вообще-то всё упирается в то, что делать, когда случилась ошибка?

E>>Э-э-э? А зачем его тогда туда переносить?

WH>И я о томже.
Ну, то есть, переписываем с нуля?

E>>(Я уж не говорю о том, что делать, если компиллер не знает таких слов...)

WH>У меня VC++8.0 и g++3.3 они понимают весьма много слов.
Ну тебе повезло.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[28]: велосипеды vs boost и пр "стандартные" решения
От: Roman Odaisky Украина  
Дата: 27.08.07 21:09
Оценка: +2
Здравствуйте, Erop, Вы писали:

E>Ну я тоже считаю, что STL-way, то есть такой способ программирования, когда можно в програме взять и заменить std::vector на std::list "если надо" -- не нужная на практике степень унификации. Но встречавшиеся мне любители связки STL + boost это дело постоянно рожают.


Да скорее это возможность один раз написать алгоритм, который работает для всех контейнеров. Т. е., не «алгоритм должен работать при замене vector на deque», а «алгоритм должен работать и для vector, и для deque». Это хороший способ избежать дублирования кода. Например, ты упоминал контейнер, хранящий пары (количество, объект). «STL way» было бы использовать SomeContainer<std::pair<std::size_t, X> > и два вида итераторов, причем оба реализуются десятком-другим строк (один из них ждет тебя уже три года
Автор: MaximE
Дата: 20.10.04
). Заметь, что этот подход позволяет выбирать разные контейнеры для разных задач, и для него автоматически становятся доступны все STL-way-алгоритмы.

Мне что больше всего нравится в STL — задание последовательностей в виде [begin, end) со специальным past-the-end-итератором. Конечно, это придумал не Степанов, такой подход и у Кнута кое-где встречается, но всё равно очень красиво.

По поводу замены контейнеров «на переправе» — да, я с тобой согласен, что это признак кривого дизайна. Потому что выбор подходящих структур данных так же важен, как и выбор алгоритмов.

E>В конце концов STL -- это же не только набор шаблонов, но и набор соглашений о том, как нужно программировать контейнеры и алгоритмы, чтобы они были все совместимы между собой.


А в большинстве других библиотек/языков невозможно/затруднительно отделить контейнеры от алгоритмов. И зря.
До последнего не верил в пирамиду Лебедева.
Re[29]: велосипеды vs boost и пр "стандартные" решения
От: Erop Россия  
Дата: 27.08.07 21:13
Оценка:
Здравствуйте, Left2, Вы писали:

L>Во! Вот это типичная ошибка — считать что контейнеры STL должны быть заменяемы друг на друга лёгким движением руки ЕМНИП, Герб Саттер, которого я очень уважаю за то что он самый большой практик из всех гуру С++, предлагал забыть об этом принципе сразу и навсегда. ПисАть код который был бы контейнеро-независимым — слишком сложно и в итоге невыгодно экономически в большинстве случаев.

Вот и я к тому же. Что люди, которые где-то как-то изучили STL, особенно если по пути ещё и зафанатели, всё время в этот грех сваливаются
Чем-то он не очень опытных программистов цепляет

L>А PowerPlant — это http://sourceforge.net/projects/open-powerplant ? Первый раз слышу. Стоящая вещь? Есть смысл смотреть?

Ну мне лично не особо понравился. ИМХО STL не такой странный. Правда open-версии я не смотрел. Но пока она была проприетарной была в смысле коньейнеров не супер. Хотя как конструктор интерфейсов содержала довольно прикольные мульки
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[29]: велосипеды vs boost и пр "стандартные" решения
От: Erop Россия  
Дата: 27.08.07 21:44
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>Заметь, что этот подход позволяет выбирать разные контейнеры для разных задач, и для него автоматически становятся доступны все STL-way-алгоритмы.


Да я понимаю плюсы STL-way. Но в целом я его всё-таки нахожу слишком сложным дляреальных задач. Так скажем.

RO>А в большинстве других библиотек/языков невозможно/затруднительно отделить контейнеры от алгоритмов. И зря.


Ну вот грубо говоря, эта самая возможность "отделить контейнеры от алгоритмов" и провоцирует в конце коноцов кукчу шаблонного кода, который никто никогда не проектировал, как шаблоны. А так как шаблоны в C++ кривенькие, и без проектирования их лучше не писать, то и код выходит кривенький (ну может у супер-пупер перцев не кривенький, выходит, но супер-пупер перцев мало )
Вот это одна из трёх моих основных претензий к STL
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[35]: велосипеды vs boost и пр "стандартные" решения
От: Roman Odaisky Украина  
Дата: 28.08.07 07:45
Оценка:
Здравствуйте, remark, Вы писали:

S>>И может быть даже удастся обойтись без мьютекса, одними CAS'ами.

R>Двухсвязанный список на CAS'ах построить достаточно не тривиально.

А может, хватит и односвязного кольцевого списка?
До последнего не верил в пирамиду Лебедева.
Re[36]: велосипеды vs boost и пр "стандартные" решения
От: Erop Россия  
Дата: 28.08.07 08:14
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>А может, хватит и односвязного кольцевого списка?

Может и хватит, но вычёркивать неудобно.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[36]: велосипеды vs boost и пр "стандартные" решения
От: remark Россия http://www.1024cores.net/
Дата: 28.08.07 08:31
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>Здравствуйте, remark, Вы писали:


S>>>И может быть даже удастся обойтись без мьютекса, одними CAS'ами.

R>>Двухсвязанный список на CAS'ах построить достаточно не тривиально.

RO>А может, хватит и односвязного кольцевого списка?


Тогда при удалении каждого указателя придётся проходить весь список, что бы найти себя сзади
Что не есть хорошо, т.к. сложность увеличивается до O(N), плюс снижается локальность обращения к памяти (т.е. придётся "потрогать" много разрозненных кусочков памяти).
Плюс встаёт вопрос, а как синхронизировать доступ к списку во время этого обхода. Толи лочить весь список на глобальном, для этой группы указателей, мьютексе (не понятно, кстати, где его хранить), толи лочить на вообще глобальном мьютексе (это вообще убийство), толи на каждый указатель делать свой мьютекс и захватывать O(N) мьютексов (что тоже звучит не особо привлекательно), толи применять lock-free reader pattern типа RCU (за исключением сложности и необходимости переделки инфраструктуры, вариант хороший).

Имхо, тут двухсвязный список — то, что доктор прописал.
...правда как его синхронизировать тоже не очевидно.
Совсем глобальный мьютекс — плохо.
Мьютекс на группу указателей — не понятно где его хранить — мы же хотим быть не интрузивными и не выделять никаких дополнительных блоков памяти.
Надо мьютекс на указатель что ли делать... я правда пока не понимаю, как это можно сделать...
У кого-нибудь есть какие-нибудь предложения...

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


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[16]: Ура! Ура! Ура!
От: Vzhyk  
Дата: 28.08.07 09:37
Оценка:
Erop пишет:
>
> Но моё ИМХО, кстати такое, что даже это не критично. Это всё неприятно
> конечно, но обычно такой параметр, как "качество и поддерживаемость
> кода" зависит не от того "С с классами" или "STL с бустом", а от
> каких-то других характеристик кода.
Ну это достаточно просто. Два наиболее важных фактора: связность кода
(модулей системы любого уровня) и его документируемость, кстати обе
характеристики тоже не количественные.
Posted via RSDN NNTP Server 2.0
Re[15]: велосипеды vs boost и пр "стандартные" решения
От: jazzer Россия Skype: enerjazzer
Дата: 28.08.07 10:29
Оценка:
Здравствуйте, Erop, Вы писали:

E>Ну самописная библиотека может быть не такой всеобъемлющей, как буст

"всеобъемлющий" — слишком расплывчатое слово.
Буст — это набор библиотек.
Никто не мешает взять оттуда необходимый (и подходящий вам) невсеобъемлющий набор библиотек (скажем, только string_algo и multi_index).

J>>А у вас в конторе не так? Новая версия самописной или третьей библиотеки (не буста, свят,свят,свят!) просто инсталлируется и используется как есть?


E>Ну при смене версий конторских либ, те, кто меняют версию, меняют и всех клиентов (это какие-то внутриконторские пользователи библиотеки) соответсвующим образом. Потмо клиенты переходят на изменённую версию.

E>Когда меняется внешняя библиотека (но такие не бывают всеобъемлющими), то те, кто поддерживают использование этой библиотеки переносият её клиентив на новую версию.

Про всеобъемлющесть я уже писал. Про остальное — не вижу в бусте никакой специфики, делающей ее в этом плане непохожими на другие библиотеки.

E>Ну так у нас тоже делали. Но потом эти изменения накапливаются и становится очень дорого поднимать верси исходнйо библиотеки

Смотря какие изменения. Если изменения сильно специфические для ваших проектов — это одно, а если вы там баг нашли (или они сами баг нашли и пофиксили его в своем SVN) — так этот багфикс и так будет присутствовать в следующей версии.

E>А если у тебя нет заказчика? Если коробочный продукт с большим числом пользователей?

Тогда им вообще слово "буст" неинтересно и ни о чем не скажет, пиши на чем хочешь.

E> ИМХО это явление социальное, а не программо-техническое... При желании задёшево затрахать персонал и внедрить потогонную систему никакой boost не помешает, как впрочем и не поможет

Ну, технический уровень персонала, качество их кода и следование стандартам разработки (в том числе какими библиотеками можно пользоваться) — это тоже явление социальное.

J>>На юниксах это делается гораздо проще: открывается сегмент общей памяти и запускается процесс, который возьмет из него данные, сделает всю работу в своей личной куче, и результат сложит обратно в общую память, после чего помрет и свою кучу с собой прихватит.

J>>И никакой возни с аллокаторами.
E>Ну это немного радикальная архитектура -- fork на каждый процесс. В конце коноцв это и на Windows можно, а вот на всяких "нетяжёлых" платформах затруднительно. Да и делать это ради ошибок, которых может и не будет, ИМХО, и не стоит.
E>Кроме того "критические ресурсы" это же не обязательно память. Это может быть временый файл, сетевое соединение, ещё что-нибудь во внешнем мире
А тогда нельзя аллокатор просто грохать, надо же, чтобы все деструкторы отработали



J>>Ну так о чем и речь. Когда язык начнет гарантировать, что данный код, помеченный данным атрибутом, защищен от любых оптимизаций (в том числе и встроенных в процессор) — тогда ы можешь гарантировать, что твой код абсолютно корректен. И для этого нужна именно поддержка со стороны языка.
E>Скорее всего ты сможешь гарантировта только исключительную тормознутость твоего кода
Сейчас, когда этого можно добиться только с мьютексами — да.

J>>Ну должны быть в язке атомарные типы, ничего ты без них переносимо не сделаешь, котому что в винде это будет какой-нть InterlocetIncrement, а в gcc — atomic_t.


E>Ну это мелкая проблема. Хотя конкртено аналог InterlocetIncrement втандартизировать наверное можно.

Где же это мелкая проблема, если это базовый блок для построения семафоров

J>>ну так есть фьючерсы, есть work stealing, много идей вообще бродит на эту тему.

E>Ну так слишком их много. Стандартизировать наверное рано.
рано, говоришь? это с 70 годов как минимум обсуждается
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[16]: велосипеды vs boost и пр "стандартные" решения
От: Erop Россия  
Дата: 28.08.07 11:05
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Никто не мешает взять оттуда необходимый (и подходящий вам) невсеобъемлющий набор библиотек (скажем, только string_algo и multi_index).

Короче. Объясняю последний раз. НЕУДОБНО. Почему? ИМХО, потому, что никто не позаботился о том, чтобы было удобно...

E>>Когда меняется внешняя библиотека (но такие не бывают всеобъемлющими), то те, кто поддерживают использование этой библиотеки переносият её клиентив на новую версию.

J>Про всеобъемлющесть я уже писал. Про остальное — не вижу в бусте никакой специфики, делающей ее в этом плане непохожими на другие библиотеки.
Ну перенести какого-то одного клиента и все проекты конторы -- это довольно значительная разница

E>>Ну так у нас тоже делали. Но потом эти изменения накапливаются и становится очень дорого поднимать верси исходнйо библиотеки

Опять повторю: ПРОБОВАЛИ (правда конкртено это не с бустом) -- НЕ ПОНРАВИЛОСЬ. Да, ткие мы вот криворукие. Видимо именно поэтому он нам и не подходит

J>Тогда им вообще слово "буст" неинтересно и ни о чем не скажет, пиши на чем хочешь.

Ну мы так и делаем. И в таких условиях буст таки сливает

J>Ну, технический уровень персонала, качество их кода и следование стандартам разработки (в том числе какими библиотеками можно пользоваться) — это тоже явление социальное.

Это безусловно особенности управления разработкой ПО, как индустриальным производством. ИМХО это ключевой момент нашего бизнеса, а вовсе и не STL/boost.
Правда мне так кажется, хотя я и не готов обосновать это мнение, что в архитектуре STL есть какой-то минорный косяк, который мешает кдобному управлению разработкой по STL-way...
Возможно это потому, что мы не умеем кправлять этим бардаком достаточно эффективно.

E>>Кроме того "критические ресурсы" это же не обязательно память. Это может быть временый файл, сетевое соединение, ещё что-нибудь во внешнем мире

J>А тогда нельзя аллокатор просто грохать, надо же, чтобы все деструкторы отработали
Ну я же писал -- регишь критические ресурсы в запросе. При откате запроса их по списочку освобождаешь...

J>

E>>Скорее всего ты сможешь гарантировта только исключительную тормознутость твоего кода
J>Сейчас, когда этого можно добиться только с мьютексами — да.
А что, от принятия стандарта C++ изменится аппаратура? Или, может быть, ОС?

J>Где же это мелкая проблема, если это базовый блок для построения семафоров

Ну она везде решена. Дело только за тем, что непереносимо. Но можно завести переносимый уровень абстракции. Их, в принципе, уже есть довольно много всяких. Но можно и стандартизировать. Эта тема, ИМХО, уже достаточно устоялась.

J>рано, говоришь? это с 70 годов как минимум обсуждается

Ну так к единообразному решению пока вроде же не пришли?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[30]: велосипеды vs boost и пр "стандартные" решения
От: Roman Odaisky Украина  
Дата: 28.08.07 13:42
Оценка: :)
Здравствуйте, Erop, Вы писали:

RO>>А в большинстве других библиотек/языков невозможно/затруднительно отделить контейнеры от алгоритмов. И зря.


E>Ну вот грубо говоря, эта самая возможность "отделить контейнеры от алгоритмов" и провоцирует в конце коноцов кукчу шаблонного кода, который никто никогда не проектировал, как шаблоны. А так как шаблоны в C++ кривенькие, и без проектирования их лучше не писать, то и код выходит кривенький (ну может у супер-пупер перцев не кривенький, выходит, но супер-пупер перцев мало :( )

E>Вот это одна из трёх моих основных претензий к STL :)

Ну вот тебе реальная задача: объединить содержимое двух упорядоченных последовательностей.
  template<typename _InputIterator1, typename _InputIterator2,
           typename _OutputIterator>
    _OutputIterator
    set_union(_InputIterator1 __first1, _InputIterator1 __last1,
              _InputIterator2 __first2, _InputIterator2 __last2,
              _OutputIterator __result)
    {
      // concept requirements
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator1>)
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator2>)
      __glibcxx_function_requires(_OutputIteratorConcept<_OutputIterator,
            typename iterator_traits<_InputIterator1>::value_type>)
      __glibcxx_function_requires(_SameTypeConcept<
            typename iterator_traits<_InputIterator1>::value_type,
            typename iterator_traits<_InputIterator2>::value_type>)
      __glibcxx_function_requires(_LessThanComparableConcept<
            typename iterator_traits<_InputIterator1>::value_type>)
      __glibcxx_requires_sorted(__first1, __last1);
      __glibcxx_requires_sorted(__first2, __last2);

      while (__first1 != __last1 && __first2 != __last2)
        {
          if (*__first1 < *__first2)
            {
              *__result = *__first1;
              ++__first1;
            }
          else if (*__first2 < *__first1)
            {
              *__result = *__first2;
              ++__first2;
            }
          else
            {
              *__result = *__first1;
              ++__first1;
              ++__first2;
            }
          ++__result;
        }
      return std::copy(__first2, __last2, std::copy(__first1, __last1,
                                                    __result));
    }

Один раз написано, один раз отлажено, один раз тщательно протестировано — и работает.
EropsMysteriousCompany::ProprietaryContainers::DynamicArray<WeHateTemplates> x, y, z;
// std::set_union(x.begin(), x.end(), y.begin(), y.end(), std::back_inserter(z));
как?
До последнего не верил в пирамиду Лебедева.
Re[37]: велосипеды vs boost и пр "стандартные" решения
От: Roman Odaisky Украина  
Дата: 28.08.07 13:54
Оценка:
Здравствуйте, remark, Вы писали:

S>>>>И может быть даже удастся обойтись без мьютекса, одними CAS'ами.

R>>>Двухсвязанный список на CAS'ах построить достаточно не тривиально.
RO>>А может, хватит и односвязного кольцевого списка?
R>Тогда при удалении каждого указателя придётся проходить весь список, что бы найти себя сзади :)

«Ну чесне слово — як діти». this->ptr = this->next->ptr; oldNext = this->next; this->next = this->next->next; delete oldNext. Заборы расставить по вкусу.
До последнего не верил в пирамиду Лебедева.
Re[38]: велосипеды vs boost и пр "стандартные" решения
От: remark Россия http://www.1024cores.net/
Дата: 28.08.07 14:07
Оценка: +2
Здравствуйте, Roman Odaisky, Вы писали:

RO>Здравствуйте, remark, Вы писали:


S>>>>>И может быть даже удастся обойтись без мьютекса, одними CAS'ами.

R>>>>Двухсвязанный список на CAS'ах построить достаточно не тривиально.
RO>>>А может, хватит и односвязного кольцевого списка?
R>>Тогда при удалении каждого указателя придётся проходить весь список, что бы найти себя сзади

RO>«Ну чесне слово — як діти». this->ptr = this->next->ptr; oldNext = this->next; this->next = this->next->next; delete oldNext. Заборы расставить по вкусу.



Это ты удалил не this из списка, а следующий элемент. Ты попробуй this удалить.


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[17]: велосипеды vs boost и пр "стандартные" решения
От: jazzer Россия Skype: enerjazzer
Дата: 28.08.07 15:33
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, jazzer, Вы писали:


J>>Никто не мешает взять оттуда необходимый (и подходящий вам) невсеобъемлющий набор библиотек (скажем, только string_algo и multi_index).

E>Короче. Объясняю последний раз. НЕУДОБНО. Почему? ИМХО, потому, что никто не позаботился о том, чтобы было удобно...

А мне вот удобно Что я делаю не так

E>Ну перенести какого-то одного клиента и все проекты конторы -- это довольно значительная разница

Еще раз — буст ничем не отличается в этом плане от любой другой библиотеки.


E>>>Ну так у нас тоже делали. Но потом эти изменения накапливаются и становится очень дорого поднимать верси исходнйо библиотеки

E>Опять повторю: ПРОБОВАЛИ (правда конкртено это не с бустом) -- НЕ ПОНРАВИЛОСЬ. Да, ткие мы вот криворукие. Видимо именно поэтому он нам и не подходит

J>>Тогда им вообще слово "буст" неинтересно и ни о чем не скажет, пиши на чем хочешь.

E>Ну мы так и делаем. И в таких условиях буст таки сливает
Не представляю, как он может в таких условиях сливать... Хотя у вас же там суперэкзотичечские платформы с суперкривыми компиляторами... Но я бы тогда, вообще-то, и не рассчитывал бы, что эти компиляторы поддерживают стандарт во всем, что не касается шаблонов. Скорее всего, у них там тоже косяков предостаточно — наверняка они время от времени не зовут вообще или зовут лишний раз деструкторы и т.д.
Я бы в таких условиях писал на чистом С.

E>Это безусловно особенности управления разработкой ПО, как индустриальным производством. ИМХО это ключевой момент нашего бизнеса, а вовсе и не STL/boost.

Согласен.

E>Правда мне так кажется, хотя я и не готов обосновать это мнение, что в архитектуре STL есть какой-то минорный косяк, который мешает кдобному управлению разработкой по STL-way...

Предлагаешь вернуться к тому нашему долгому обсуждению STL-way? Я, вроде, показал на конкретном примере, что STL-way (или, если не нравится это слово, вообще подход алгоритмы <=> итераторы <=> контейнеры, его не обязательно реализовывать именно на STL, просто в STL она во главе угла) отлично работает и очень удобен. Если, конечно, компилятор вменяемый (хотя бы на уровне вц6).

E>Возможно это потому, что мы не умеем кправлять этим бардаком достаточно эффективно.

Мне сложно судить, сам понимаешь

E>>>Кроме того "критические ресурсы" это же не обязательно память. Это может быть временый файл, сетевое соединение, ещё что-нибудь во внешнем мире

J>>А тогда нельзя аллокатор просто грохать, надо же, чтобы все деструкторы отработали
E>Ну я же писал -- регишь критические ресурсы в запросе. При откате запроса их по списочку освобождаешь...
Тогда непонятно, причем тут твои рассуждения про аллокатор, когда тебе нужен типизированный (скорее всего) контейнер.

J>>

E>>>Скорее всего ты сможешь гарантировта только исключительную тормознутость твоего кода
J>>Сейчас, когда этого можно добиться только с мьютексами — да.
E>А что, от принятия стандарта C++ изменится аппаратура? Или, может быть, ОС?
нет, появятся гарантии, что если ты написал какое-то выражение, то оно выполнится именно так, как ты написал, и ты сможешь это гарантировать безо всяких шаманских плясок, коими радует нас remark (я имею в виду его пост про double lock).

J>>Где же это мелкая проблема, если это базовый блок для построения семафоров

E>Ну она везде решена. Дело только за тем, что непереносимо. Но можно завести переносимый уровень абстракции. Их, в принципе, уже есть довольно много всяких. Но можно и стандартизировать. Эта тема, ИМХО, уже достаточно устоялась.

Ну вот и стандартизируют. Что и требовалось. С чем ты споришь-то?

J>>рано, говоришь? это с 70 годов как минимум обсуждается

E>Ну так к единообразному решению пока вроде же не пришли?
Так потому что на каждую задачу требуется свое решение.
Хотя, конечно, есть некоторые тормозные, но безотказные вещи (мьютексы), которые, как самое простое для понимания, вцементированы в некоторые языки в виде слов типа synchronized. Чем не единообразное решение
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[31]: велосипеды vs boost и пр "стандартные" решения
От: Erop Россия  
Дата: 29.08.07 07:31
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>Ну вот тебе реальная задача: объединить содержимое двух упорядоченных последовательностей.


0) Ты привёл код, который делает не то, что ты просил. Он ещё и повторы выбрасывает, вернее не совсем так. Если одинаковое значение есть и в первой и во второй последовательности, то в результирующую последовательность кладёт только одно значение. А вот если в исходных последовательностях есть повторы, то поведение неопределено. Наверное предполагается, что в исходных последовательностях повторов нет, но это от чего-то не проверяется

1) Это стандартный алгоритм, его таки проектировали, я надеюсь

2) Мне кажется, что он нужен довольно редко

3) Даже если двухпутевое слиение написать "из головы", оно у нормального программиста обычно работает сразу. ИМХО лучше уметь программировать любой алгоритм, чем уметь пользоваться merge. Тем более, что набор алгоритмов в STL ИМХО никакой состематичностью не обладает. Хотя это не совсем двухпутевое слияние, конечно, так как повторы не копируются.

4) (И это главное, на самом деле) Это очень абстрактная задача. Реальная задача звучит как-то так: "Рассчитать аэродинамику такого-то самолёта"




RO>
RO>EropsMysteriousCompany::ProprietaryContainers::DynamicArray<WeHateTemplates> x, y, z;
RO>// std::set_union(x.begin(), x.end(), y.begin(), y.end(), std::back_inserter(z));
RO>как?
RO>


Ну совсем так я не знаю, а если просто выбрасывать повторы, то так:
x.CopyTo( z );
z.SortedMerge( y );
RemoveDuplicatesInSortedArray( z );


Или даже так:
assert( !HasDuplicatesInSortedArray( x ) && !HasDuplicatesInSortedArray( y ) );
x.CopyTo( z );
z.SortedMerge( y );
RemoveDuplicatesInSortedArray( z );


Правда мне обычно RemoveDuplicatesInSortedArray не требуется. Вернее так, если требуется, то используется другая структура данных (собственно множество)
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[29]: велосипеды vs boost и пр "стандартные" решения
От: Erop Россия  
Дата: 29.08.07 08:05
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>«STL way» было бы использовать SomeContainer<std::pair<std::size_t, X> > и два вида итераторов, причем оба реализуются десятком-другим строк (один из них ждет тебя уже три года
Автор: MaximE
Дата: 20.10.04
).

Очевидно, что так можно сделать и без STL и даже без STL-way, но ИМХО понятие "масив" который как-то хитро хранит потроха и имеет возможности необычной итерации намного удобнее для использования чем эта вот конструкция. Конечно в конце концов её можно завернуть в шаблон класса и выставить наружу два итератора. Такой и сякой. И мы получим итераторы к тем же данным. То есть, ИМХО, эквивалентное решение. Если тебе удобно мыслить на языке итераторов, то оно тебе будет органично, а если на языке массивов, то нет. На этом различия заканчиваются...

RO>Заметь, что этот подход позволяет выбирать разные контейнеры для разных задач, и для него автоматически становятся доступны все STL-way-алгоритмы.

Заметь, что в качестве примера "реальной задачи" ты привёл очень абстрактную математическую конструкцию. Да ещё и неудачно, ИМХО, реализованную (я бы хотел проверки отсутствия повторов в исходных последовательностях в _DEBUG версии программы)
И это код написанный спецами!!!

RO>Мне что больше всего нравится в STL — задание последовательностей в виде [begin, end) со специальным past-the-end-итератором. Конечно, это придумал не Степанов, такой подход и у Кнута кое-где встречается, но всё равно очень красиво.


Да, завести маркер конца во многих алгоритмах очень удобно!!!
Мне такая шняга тоже нравится!!!
Поинт в том, что эти все алгоритмы нужны таки редко, а маркер конца тягать за собой надо всё время.
То же двухпутевое слиение, можно записать и без конца. Вот смотри (пишу специально с "итераторами", чтобы быть понятным, зато "из головы"):
template<class TArray&>
class CSortedArraysMerger {
public:
    static void Process( const TArray& src1, const TArray& src2, TArray& dst )
    {
        CArrayIterator i1( src1 );
        CArrayIterator i2( src2 );
        TArray buffer;
        for( ; ; ) {
            if( i2.IsEnd() ) {
                i1.CopyRestTo( buffer );
                break;
            } else {
                i1.CopyLessOreEquTo( i2, buffer );
            }
            if( i1.IsEnd() ) {
                i2.CopyRestTo( buffer );
                break;
            } else {
                i2.CopyLessOreEquTo( i1, buffer );
            }
        }
        assert( i1.IsEnd() && i2.IsEnd() && src1.Size() + src2.Size() == buffer.Size() );
        buffer.MoveTo( dst ); // Можно и std::swap( dst, buffer ); 
    }

private:
    struct CArrayIterator {
        const TArray& Data;
        int Index;
        
        CArrayIterator( const TArray& src ) : Data( src ), Index( 0 ) {}
        bool IsEnd() const { return Index >= Data.Size(); }
        void CopyRestTo( TArray& dst )
        {
            while( !IsEnd() )
                dst.Add( Data[Index++] );
        }
        void CopyLessOreEquTo( CArrayIterator& other, TArray& dst ) 
        {
            assert( !other.IsEnd() );
            while( !IsEnd() && Data[Index] <= other.Data[other.Index] )
                dst.Add( Data[Index++] );
        }
    };
};

template<typename T>
void MergeSorted( const CErrorsMysticArray<T>& src1, 
    const CErrorsMysticArray<T>& src2, CErrorsMysticArray<T>& dst )
{
    CSortedArraysMerger< CErrorsMysticArray<T> >::Process( src1, src2, dst );
}
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.