VolatileRead -Write просто блокирует память занимаемой под переменную в момент обращения к ней, а одновременность повторяю, это иллюзия, у вас в любом случаи не_что не_выполняется одновременно, даже ваши потоки, сколько бы их ни было. пример: (условно он выглядит так): глобальная переменная сигнал для потока. каждый поток имеет бесконечный цыкл While(true) в нем все выполняется асинхронно (типа не зависимо одновременно). Далее в каждом цикле потока есть условие срабатывающее по глобальному сигналу для каждого потока, которое исполняет код синхронизации, запись в глобальные переменные, или глобальные структуры или объекты не важно, главное чтоб при обращении к ним блокировалась память занимаемая ими, тогда легко можно упорядочить доступ к ней, так как в компьютере все выполняется последовательно, а одновременность это иллюзия. (к примеру if (VolatileRead(global) = =1) - сработает условие в первом потоке, if (VolatileRead(global)= =2) во втором потоке и тд, а в самом цикле while(true)выполняется код постоянно). Надеюсь понятно, иначе в любом случаи вы получите кашу. Задержки не будет, так как условие будет срабатывать в другом потоке.
У меня 3 ядра, а не 1, так что нет. Возможно до 3 одновременно выполняющихся потоков.
Кроме того, никто не отменял GPU.
Нет, оно ещё смывает кеш процессора процессора. Поэтому lock лучше.
ваши ядра хоть и работают асинхронно(не зависимо) но результат они также синхронизируют, должны же они как то упорядочивать его, просто все происходит по быстрей, а при сложении мозаики в любом случаи синхронизация(слияние в упорядоченный вид).
Не после каждого такта. Я тут в подробности не вдавался, но вроде там в кеше сохраняются последние изменения, а смываются в оперативку только когда необходимо.
Я тоже примерно понимаю общий смысл, но на словах легко упустить детали реализации. Поэтому я и прошу пример. Ну и вчитываться в эту стену текста нет желания, вы даже на абзацы не разбиваете… В общем давайте код, он громче текста говорит.
есть volatile при оглашении переменных в не_управляемом коде, а мы с вами говорим про управляемый код, там не нужно это слово писать при оглашении переменной, просто создаешь глобальную переменную, если это с# то пишешь public int a; а если С++ то просто в глобальном пространстве имен пишешь int a;.
хорошо дам код, а вы мне пример с lock обращением из другого потока в управляемом коде. пример дам чуть позже, я сейчас серфю в не дома. ну и как через foreach вывести глобальный массив к которому обращаются потоки(дело в том что foreach не принимает слудующую конструкцию foreach(int a VolatileRead(mas)) , по этому в момент вывода из массива в некоторые ячейки продолжается асинхронная запись из других потоков).
Кхм, действительно, управляемый код сам всё синхронизирует:
var
state := 0;
procedure p1;
begin
while true do
begin
while state mod 2 <> 0 do;
writeln(state);
state += 1;
end;
end;
procedure p2;
begin
while true do
begin
while state mod 2 = 0 do;
writeln(state);
state += 1;
end;
end;
begin
System.Threading.Thread.Create(p1).Start;
System.Threading.Thread.Create(p2).Start;
end.
И в данном случае, получается, не VolatileRead
не lock
не нужно.
Что касается for:
var
state := -1;
a := new integer[50];
procedure p1;
begin
for var i := 0 to a.Length - 1 do
begin
a[i] := i;
state := i;
end;
write('done write'#10);
end;
procedure p2;
begin
for var i := 0 to a.Length - 1 do
begin
while state < i do;
write(a[i]+#10);
end;
write('done read'#10);
end;
begin
System.Threading.Thread.Create(p2).Start;
System.Threading.Thread.Create(p1).Start;
end.
В данном случае синхронизация нужна только на случая лага, потому что запись получается всегда быстрее вывода.
А, подождите, вы случайно не про то что переменная foreach не обновляется если этот элемент массива изменён в другом потоке? Чтоб обновлялась - надо чтоб элементы массива были ссылочного типа, иначе foreach копирует их.
понятно, вот по этому в моем случаи foreach не подходит. Далее, если в ваших потоках только в определенное время должна производится запись в глобальные переменные, а остальное время они выполняют другой код, то без синхронизации не обойтись. Далее, если мне нужно сделать шаг в тысяча потоках то мне не помогут последовательности, капля по капле у меня возникнут тормоза. Мне нужен for c условиями , а дополнительные переменные в цикле while тоже накладно. С циклом while код засоряется, сначала на уровне оглашения, затем в условие(но это ладно), затем в счетчике, а если у меня 100 вложенных циклов с шагом while то это 100 переменных под счетчики??? это же полный абзац…)))
Это лишь значит что вы пишете говнокод)) В нормально коде столько потоков и вложенных циклов не надо… Кроме того, больше 5 вложенных блоков кода - тоже уже считается плохим тоном. Надо разделять на типы и методы.
И, насчёт
Вам никто не мешает обернуть value-тип в класс. И уже делать массив этого класса.
А при чём тут они? Они помогают сделать код красивее, но только когда вам нет дела до производительности.
1000 асинхронных потоков по моему это мизер особенно для будущего, ну что такое 1000 независимых нейронов??? акстись ты бредишь. А гавна код -это код урезанных стандартов, во всех языках for полноценный, а в паскале он урезан, с какой целью???, он что какой то специализированный язык, заточен к примеру как визуал байсик под определенные цели? - не понимаю зачем в паскале нужен цикл for, если даже последовательности это достоинства CLR. И какой бы ни был мой код изначально это прорыв в понимании. Нужно в начале 100 вложений сделать, это возможно, значит буду делать эти 100 вложений лишь бы работало, на кишки никто не смотрит, главное результат. дальше больше, совершенствуй код, а если ты не знаешь возможно ли это, ты наверное кричишь однозначно это не возможно, нет в тебе духа экспериментатора, и не нужно мне советовать бред, я знаю как выуживать информацию из тьмы, а глядя на твои размышления я убеждаюсь, в том что твой креатив ограничивается чужими стандартами, в общем ты далек от креатива потому как опираешься на красоту не известных кишек, следовательно ты ждешь красоты в место того чтоб ее создавать и ее не будет, потому как ты не знаешь как она выглядит, а чтоб пробовать ты себя ограничиваешь. Только не думай что я с тобой ругаюсь, мне это не интересно.
- вот видишь ты сам сейчас подтвердил что код на паскале это гавна код, сплошные панты через жопу. последовательности в for это и есть гавна код, код через жопу…)))) достаточно иметь адекватный For как в других языках, это стандарт циклов для всех языков, а в паскаль это извращение, когда можно на прямую приходится выеживаться. И не говори гоп про вложения пока не перепрыгнешь, сначала всегда пишется говна код, по типу как виртуальные методы или интерфейсы, наброски черновики, а затем уже реализовываешь, так и тут я вижу алгоритм создаю и убеждаюсь что он работает и начинаю его совершенствовать. К примеру когда я создавал свой первый алгоритм по комбинаторики он вычислял все значения комбинации манипулируя дробями, затем постепенно пришел возможности делать тоже самое используя целые числа, в итоге алгоритм стал быстрее и проще. Так что я думаю ты программист еще тот, делаешь все чтоб сказать, что это не получится…))) иначе бы ты ценил любую возможность которая помогает зацепиться. Все дело в том, что пока ты на уровне не познанного ты получаешь ассоциативный план неизвестности, а когда ты уже на уровне познания то ты постепенно проявляешь совершенный код, приближая его ассоциациями нового уровня. Есть люди которые начинают дразнится, а есть люди которые пробуют любые пути, а затем протаптывают дорогу. Ну я думаю ты этого не поймешь, не твой уровень. Тебе еще потоки учить нужно, а то у тебя три ядра одновременно последовательность рисуют…))
Ну, это бред для каждого делать поток. Поток кроме всего прочего занимает очень много места в оперативке под всякое, не самое нужное. Это всё надо делать через GPU. А для GPU свои отдельные языки не просто так придумали.
Ну, последовательности это фича .Net)) И там они так же. Когда нужна производительность - в любом случае придётся опускаться на более нижние уровни и отказываться от любого сахара. И если заменить for на тот же while - есть очень много того что оказывается можно улучшить.
Я вам очень советую всё же посмотреть декомпиляторами на то, во что разворачивается код на разных языках. В C# всё не так ужасно как в паскале с for, но всё равно полно того что можно улучшить.
Но вы полностью правы в том что паскаль не подходит для макс оптимизации. Разработчики давно пришли к выводу что ниша языка образовательная. Вообще нужно писать на более низкоуровневых языках, вроде C++ , если так уж нужна производительность.
И - извините, но я всё же не буду читать всю стену текста на 2 страницы, без форматирования и с кучей ошибок (даже такой нуб в грамматике как я замечает, а вообще то браузер проводит проверку грамматики сам, вам нужно только тыкать ПКМ по тому что выделяет красным). А в этот раз ещё и первая часть вся в чём то вроде капса. На форуме есть предпросмотр сообщений, так что от вас остаётся только не поленится и посмотреть туда, чтоб заметить это…
ну начинается грамматика… да это моя криптография для тебя…))) я кстати исправляю их по красным подчеркиваниям, можешь скопировать и посмотреть. (если допущена ошибка то смысл потерялся? а если смысл потерялся то как ты нашел ошибку, если этот смысл ты не знал? у тебя что буйное воображение?) При отправке сообщения мне сказали ждите 7 часов, по этому я все засунул в одно, а засунулось оно как то большим. так что экскюзьми мамаша гиря…)))- к стати попробуй найди ошибку в пред последнем предложении.
К стати, раз PascalABC подходит только в образовательных целях то к правильным вещам нужно привыкать сразу, иначе рефлексы, горе программисты и все такое обеспечено, а это уже Государственная проблема. Так что цикл For должен быть правильным как в большинстве языков.
Не надоело еще сотрясать воздух? Цикл for в Паскале такой, какой он в Паскале. В Паскале, понимаете это? Не в Си, в Бейсике или Фортране. В Паскале. Это не Вы определяете, каким ему быть, а синтаксис языка. Либо Вы тролль, либо Вы, простите, просто неадекватны.
Логика в том, чтоб не ломать старое, а только добавлять новое.
совершенно верно! цикл For с условием в определении - это новшество в Pascal, а не делают его потому что сами сидят на других языках где используют вложенные циклы без напряга, тупые маньяки, типа крутые программисты - это те программисты которые умеют смеяться над другими программистами, принцип лохов и тормозов развития. фу мерзость.
Переведи на С++ вот из С#
System.Threading.Tasks; - параллельное программирование
var tok1 = Task.Factory.StartNew(() => // внешняя задача (создание потока.)
{
//код для выполнения в потоке tok1.
var tok2 = Task.Factory.StartNew(() => // вложенная задача(создание потока в потоке)
{
//код для выполнения во вложенном потоке tok2.
}, TaskCreationOptions.AttachedToParent);
});
//если указать слово TaskCreationOptions.AttachedToParent - то вложенные потоки становятся зависимыми от внешних потоков, хоть и задачу свою будут выполнять параллельно но завершит работу внешний поток.
Типа сложная и многословная задачка?
Пример раз (настоящие таски, тру concurrency, требует Qt).
auto fut = QtConcurrent::run([&]() {
//write your code here
});
...
fut.waitForFinished();
Пример два (исключительно стандартная библиотека С++11, именно поток, а не Task).
std::thread thr([&]() {
//write your code here
});
...
thr.join();
По-моему (впрочем, не буду настаивать), тут явный (и гхм, глупый) наезд на разработчиков и администрацию сайта. За такое надо банить. ИМХО.
сам себя за бань, ты случаем не параноик ??? мерещится тебе все…
я знаю этот человек всегда дает примеры достойные внимания, вот и попросил его, потому как на C# все просто, а на С++17(а не 11) не могу понять как это делается.
Сами разработчики С# рекомендуют использовать Task из (System.Threading.Tasks;)
в силу многоядерных процессоров…
std::thread - это уже прошлый век.
Все задачи сложные, от слова сложить, смысл упорядочить. А, как ты это понимаешь одному тебе известно. Не известно - сложно, Известно - полегче.
Было бы тебе легко ты бы ответил конкретно на Task, а не стал бы тут лепить кренделя из библиотек про которые я не спрашивал.