Здравствуйте, Константин Л., Вы писали:
К>>Дороговизна не в переключениях, а в атомарных операциях.
КЛ>А я о чем?
К>>Комплект функций синхронизации — атомарные операции, мьютексы-шмютексы — предоставляемый операционной системой приложению, различается для одно- и многоядерных систем.
Да в общем, всё о том же.
Вытесняющая многозадачность дороже кооперативной. Многоядерность дороже одноядерности. Хотя и удобнее, и эффективнее при разумном использовании.
О том ремарк и пишет: с помощью серебряной пули можно выстрелить себе в ногу
Здравствуйте, Константин Л., Вы писали:
КЛ>Здравствуйте, remark, Вы писали:
R>>Здравствуйте, сипласплас, Вы писали:
С>>>btw, после прочтения введения в lock/wait free Александреску мне показалось, что они хорошо ложатся на GC
R>>Что значит "ложатся"? И что значит "хорошо"? R>>Определённо их можно реализовать в присутствии GC. Это даже немного легче. R>>Но их так же можно реализовать и без GC. R>>Моё личное мнение, что без GC будет быстрее и масштабируемее. Я не уверен, что какой-либо алгоритм GC может приблизиться к RCU.
КЛ>??? Либо я совсем не в теме, либо GC помогает забить на memory management в RCU
??? достаточно *либо* GC, *либо* RCU, иметь их вместе бессмысленно.
Здравствуйте, Andrei F., Вы писали:
AF>Здравствуйте, remark, Вы писали:
R>>Обмен идёт через кэши.
AF>Есть какие-то другие виды обмена кроме того, который иницируется явно при помощи барьера памяти?
Обмен инициируется не барьерами, а сохранениями/загрузками из памяти.
Других я не знаю.
Мессджинг... но тогда придётся в обязательном порядке делать *жёсткую* привязку *всех* потоков к ядрах. А иначе как? Какому ядру посылать сообщение? Это уже переведёт систему ближе к кластерам...
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, remark, Вы писали:
R>>dlmalloc: R>>http://gee.cs.oswego.edu/dl/html/malloc.html
E>Кстати, сам Дуг Ли советует для многопоточных программ использовать ptmalloc, производный от dlmalloc. Но он только Unix-овый.
E>А dlmalloc, по слухам, в большинстве Linux-ов является частью libc и поэтому там он как раз штатный аллокатор.
Здравствуйте, сипласплас, Вы писали:
С>Здравствуйте, remark, Вы писали:
С>[]
R>>К сожалению, *никакой*!
R>>Можно пошариться по готовым библиотекам. Базовые Interlocked скорее всего можно будет найти. Можно ACE посмотреть. R>>С портируемыми барьерами памяти всё значительно хуже. В ядре линукса можно найти жалкое подобие с убогим С интерфейсом. R>>Скорее всего писать самому.
С>Но почему ты не делаешь барьер памяти?
Здравствуйте, remark, Вы писали:
R>>>dlmalloc: R>>>http://gee.cs.oswego.edu/dl/html/malloc.html
E>>Кстати, сам Дуг Ли советует для многопоточных программ использовать ptmalloc, производный от dlmalloc. Но он только Unix-овый.
E>>А dlmalloc, по слухам, в большинстве Linux-ов является частью libc и поэтому там он как раз штатный аллокатор.
R>Главное не использовать виндовый
Все это хорошо пока ты стороние библиотеки в свой проект не подключаешь. А как возьмешь к себе ACE, PCRE, Crypto++, да еще в виде DLL, так и запаришься в них нестандартные аллокаторы запихивать.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, remark, Вы писали:
R>>>>dlmalloc: R>>>>http://gee.cs.oswego.edu/dl/html/malloc.html
E>>>Кстати, сам Дуг Ли советует для многопоточных программ использовать ptmalloc, производный от dlmalloc. Но он только Unix-овый.
E>>>А dlmalloc, по слухам, в большинстве Linux-ов является частью libc и поэтому там он как раз штатный аллокатор.
R>>Главное не использовать виндовый
E>Все это хорошо пока ты стороние библиотеки в свой проект не подключаешь. А как возьмешь к себе ACE, PCRE, Crypto++, да еще в виде DLL, так и запаришься в них нестандартные аллокаторы запихивать.
Да, этим грешит большинство библиотек.
Хотя вот насколько помню в OCI (Oracle call interface) в самую первую функцию инициализации можно передать указатели на функции аллокации/освобождения памяти. Приятно.
, что используешь nothing (т.е. вообще без какой-либо синхронизации кешей), тк *есть* std::atomic. Или ты используешь какой-то вариант std::atomic?
С>Я в конец запутался
С использованием std::atomic я показал, как должна была бы выглядеть программа для сферического компьютера в вакууме. Т.е. где должны быть какие типы барьеров.
Потом я сказал, что те типы барьеров, которые тут должны быть на сферическом компьютере, на x86 не нужны, т.к. всегда присутствуют неявно.
Т.е., если я пишу под x86, то я ничего не использую.
Здравствуйте, Константин Л., Вы писали:
КЛ>Здравствуйте, remark, Вы писали:
КЛ>[]
R>>Главное не использовать виндовый
КЛ>А что ты делаешь с 3rd party libs?
Здравствуйте, remark, Вы писали:
R>Здравствуйте, AVM, Вы писали:
AVM>>IMHO самое основное, что мешает жить и что является первичной проблемой — как разделять данные.
R>Я это и говорю: R>
R>*каждое* ядро должно быть обеспечено *своей* работой и *своими* данными, и работать над ними *независимо*.
Да, я видел, я просто подчеркнул где на мой взгляд корень проблемы.
R>Скорее всего они занимаются распараллеливанием какого-то подмножества задач. Или вообще HPC.
Подмножество задач, но с закладыванием перспективы на будущее.
Здравствуйте, Andrei F., Вы писали:
AF>Здравствуйте, remark, Вы писали:
R>>Не обязательно
AF>И как ты себе это представляешь? На примере простой задачи поиска элемента в массиве простым перебором, например.
Ключевое слово, по которому надо искать — work stealing.
Так же ищи — Cilk, Java Fork/Join, C# TPL, Intel TBB. Как это ни удивительно, но все эти вещи используют идентичный механизм.
R>>Распараллеливать работу на уровне отдельных машинных инструкций определенно не стоит.
AF>см выше. У меня есть сомнения, что есть смысль параллелить эту задачу в рамках существующей архитектуры при размере массива < ~100 элементов. Может быть, даже 1000.
Если *всё*, что надо сделать твоей программе — это обработать 100 элементов, то я не думаю, что у тебя есть проблемы вообще.
Здравствуйте, AVM, Вы писали:
R>>Скорее всего они занимаются распараллеливанием какого-то подмножества задач. Или вообще HPC. AVM>Подмножество задач, но с закладыванием перспективы на будущее.
По поводу подмножества охотно верю, а по поводу вообще:
Их технология в перспективе сможет сделать мой врождённо однопоточный сетевой сервер или ядро БД линейно масштабируемым на N ядер? Можешь спросить у них... Или просто сам подумать
[]
R>С использованием std::atomic я показал, как должна была бы выглядеть программа для сферического компьютера в вакууме. Т.е. где должны быть какие типы барьеров. R>Потом я сказал, что те типы барьеров, которые тут должны быть на сферическом компьютере, на x86 не нужны, т.к. всегда присутствуют неявно. R>Т.е., если я пишу под x86, то я ничего не использую.
Т.е. ты хочешь сказать, что Interlocked _вообще_ никогда не нужен и все само собой синхронизируется? Для меня это большая новость. О чем же тогда пишет Рихтер в своей "Programming for Win2k"? Да ты Галилей получается, а мы средневековые узколобые создания (это типа не стеб, а попытка показать насколько твое "открытие" может меня шокировать)!
Правльно ли я понимаю, что:
1. Имеем переменную в кеше процессора1
2. Имеем ее значение в кеше проца2
3. При её изменеии в проце1 новое значение *автоматически" переезжает в кеш процессора 2, т.е. конструкия someptr = 0x00000000 выльется в нечто напоминающее InterlockedExchangePointer?
Здравствуйте, remark, Вы писали:
R>Здравствуйте, AVM, Вы писали:
R>>>Скорее всего они занимаются распараллеливанием какого-то подмножества задач. Или вообще HPC. AVM>>Подмножество задач, но с закладыванием перспективы на будущее.
R>По поводу подмножества охотно верю, а по поводу вообще: R>
R>Их технология в перспективе сможет сделать мой врождённо однопоточный сетевой сервер или ядро БД линейно масштабируемым на N ядер? Можешь спросить у них... Или просто сам подумать
Пасиб за ссылку, на досуге посмотрю. Сможет или нет не знаю, я очень давно от этих задач отошел — можно даже сказать серьезно и не начинал ими заниматься. Проблема разделение доступа к данным лежит на поверхности.
Ну а если уж сваливаться на философию, то мое мнение начинает сдвигаться в сторону что развитие современных кремниевых процессоров — тупиковая ветвь. Какая разница 4 или 80 или 8000 ядер. Качественный скачек это не дает, просто порождает кучу проблем и обсуждений на форумах.
С другой стороны у каждого из нас в голове содержится нехреновый такой вычислительный центр додключенный к обалденным устройствам ввода/вывода
R>
Without a garbage collector, things get harder. Much harder, actually, and it turns out that deterministic memory freeing is quite a fundamental problem in lock-free data structures.
А вот про то, что GC поможет RCU, я похоже, погорячился
R>>> R>
Здравствуйте, AVM, Вы писали:
AVM>С другой стороны у каждого из нас в голове содержится нехреновый такой вычислительный центр додключенный к обалденным устройствам ввода/вывода
А с какой скоростью и с какой точностью сможешь перемножить две матрицы 100x100 действительных чисел в уме?
Здравствуйте, remark, Вы писали:
R>??? достаточно *либо* GC, *либо* RCU, иметь их вместе бессмысленно.
Главная идея RCU (http://en.wikipedia.org/wiki/Read-copy-update оно?) это неизменение разделяемых данных, а изменеие ссылки по которой эти данные получают на ссылку на обновленные данные.
Те GC не отменяет RCU. Но делает реализацию данного паттерна тривиальной.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, сипласплас, Вы писали:
E>>>Но, на двух ядрах оказывается, что стоимость переключения контекста между нитью-обработчиком и нитью ACE_Reactor-а слишком высока, чтобы передавать входящий/исходящий трафик через очереди сообщений.
С>>При чем здесь это? Чем оно дороже чем на одноядерной машине?
К>Дороговизна не в переключениях, а в атомарных операциях. К>Комплект функций синхронизации — атомарные операции, мьютексы-шмютексы — предоставляемый операционной системой приложению, различается для одно- и многоядерных систем.
К>На 1 ядре atomic_xxx — это К>- запретить прерывания — чтобы планировщик не вломился и не вытеснил поток К>- выполнить операцию К>- разрешить прерывания
Не могу не вмешаться
Скажу за x86.
На 1 ядре atomic_xxx — это
— запрещать прерывания не надо — т.к. операции, которые выполняются как атомарные, всегда состоят из одной машинной команды, а прерывания не действуют на уровне микрокоманд
— выполнить операцию
Хотя тут некоторая загвоздка. Т.к. что бы добиться такого эффекта надо либо компилировать свою программу исключительно под одно ядро, либо делать как в ACE — при старте программы смотрим сколько ядер в системе и устанавливаем соотв. обрабом глобальные указатели на правильные функции atomic_xxx.
Итого это занимает порядка тактов.
Если использоват "честные" atomic_xxx, то даже на одноядерном процессоре Intel это выливается в 100 тактов.
К>А на многоядерном — это К>- запретить прерывания К>- заблокировать память — чтобы остальные ядра туда не выстрелили К>- выполнить операцию К>- разблокировать память К>- разрешить прерывания
А на многоядерном — это
— запретить прерывания — опять не надо
— заблокировать память/или строку кэша, что немного дешевле и масштабируемее
— выполнить операцию
— разблокировать память/строку кэша
Итого это занимает порядка 100 — 450 тактов (в зависимости от статуса кэш линии)
Но основная беда даже не в этом.
(опустим пока такие тривиальные вещи как сериализация на мьютексах)
Передача кэш-линии занимает порядка 150-350 тактов. Даже без всяких атомарных операций и пр.
Т.е. скорость работы снижается до 100 (!) раз. Т.о. тривиальный producer-consumer может стать ботлнеком, если данные просто переходят из одного кэша в другой (без всяких atomic, мьютексов, евентов, вызовов я ядро для пробуждения consumer).
Плюс шина межпроцессорного/межядерного взаимодействия может стать боттлнеком, так что приложение просто не будет масштабироваться вообще при добавлении ядер, даже если потоков/работы достаточно, и нет сериализации на мьютексах, ядра не загружены и шина памяти не загружена.