Schedulable lightweight virtual processes and concurrent loops P&L: -11.5 (≃ -118 EUR)

An approach to building concurrent software
YAML Projektas Produktai

Imagine a nested for loop, it is composed of multiple loops. We can simulate concurrency by executing parts of loops and rapidly switch between them.

This is what a kernel scheduler does and I think it's a very interesting part of an operating system. Unfortunately most programs are not written to be multithreaded so computers use very little of resources available to them.


Metinis IRR: -1.0000
Naujausias NPV@diskonto norma=0.1: -11.4888 ħ (-118.10 EUR)
(nesiųsti pranešimų) Prašome prisijungti.

(nesiųsti pranešimų) Prašome prisijungti.

(nesiųsti pranešimų) Prašome prisijungti.

(nesiųsti pranešimų) Prašome prisijungti.

(nesiųsti pranešimų) Prašome prisijungti.

(nesiųsti pranešimų) Prašome prisijungti.

(nesiųsti pranešimų) (nebūtinas) Prašome prisijungti.

Įdomus. Jūs nenaudojote savojo [concurrency in Python] palaikymo (https://docs.python.org/3/library/concurrency.html) ir naudojote tik pagrindinį išvardinimą, indeksavimą ir priskyrimą. Manau, kad to reikia suprasti. Tai turi edukacinę vertę.

Interesting. You did not use any native support for concurrency in Python, and used only basic enumeration, indexing, assignment. I guess, that is what it takes to understand. This has educational value.

(nesiųsti pranešimų) Prašome prisijungti.

Štai kodėl aš tai vadinu virtualiu lygiagrečiu. Norėdami užtikrinti IO lygiagretumą, turėsite naudoti gijas Neįmanoma sukurti visko, kas sukasi amžinai arba blokuoja. Taigi toliau parašysiu visą savo kodą, kad niekada neblokuočiau ir nepasikartotų. Tai svarbi pamoka, kurią išmokau kurdamas daugiasriegio planavimo priemonę.

Blokavimas programai nematomas. Programa nežino, kad ji blokuoja. Turite žinoti, kad metodas gali blokuoti, kad jį apeitų. Kita mano idėja yra lygiagreti, o darymo ciklas, kuris pakeičia blokavimą į neblokuojantį per sintaksinį cukrų. Tai atrodo taip

A1 = lygiagreti, o { Buf = socket.recv(1024) } Daryk { Lygiagretus (Socket socket : sockets) { Socket.send(buf) } } Crossmerge A1

Ši sintaksė sukasi kelias gijas, kurias blokuoja gavus duomenis. Ir kiekvienam iš jų jis sukasi siūlą gijų telkinyje, kad galėtų jį apdoroti ir lygiagrečiai siųsti į kiekvieną jungtį.

Dar viena mintis, kurią turiu, yra pakeisti prioritetinę vykdymo tvarką. To kodo planuotojas kiekvieną kartą sutvarko žymes ta pačia tvarka. Nėra jokios priežasties, kodėl kai kurių kilpų negalėtume vykdyti labiau nei kitų.

That's why I call it virtual concurrency. You would need to use threads to provide IO concurrency Anything that loops forever or blocks cannot be composed. So I shall write all my code going forward to try never block and be reetrant. This is an important lesson I learned while developing my multithreaded scheduler.

Blocking is invisible to the program. The program isn't aware it is blocking. You need to know that a method can block to work around it. My other idea is a parallel while do loop which changes blocking to be non blocking through syntactic sugar. It looks like this

A1 = parallel while { Buf = socket.recv(1024) } Do { Parallel for (Socket socket : sockets) { Socket.send(buf) } } Crossmerge A1

This syntax spins up multiple threads to block on receiving data. And for each one it spins up a thread in a thread pool to handle it and send it to every connection in parallel.

Another idea I have is to change the priority execution order. That scheduler in that code round robins the tickers in the same order every time. There's no reason why we cannot execute the loops some more than others.



    : Mindey
    :  -- 
    :  -- 
    

chronological,
(nesiųsti pranešimų) Prašome prisijungti.

Pridursiu, kad vienam siūlui reikia tik vienos while (true) kilpos. Visa kita gali būti vienu metu suplanuota gijoje.

I shall add that you only need one while (true) loop per thread. Everything else can be concurrently scheduled within a thread.



    :  -- 
    : Mindey
    :  -- 
    

chronological,
(nesiųsti pranešimų) Prašome prisijungti.

Turiu parašyti Joinable Ticker, kuris laukia įvesties iš kelių žymenų prieš siųsdamas išvestį. Tai leidžia mums sukurti vamzdynus, kurie skaidosi ir susilieja.

I need to write a Joinable Ticker that waits for inputs from multiple tickers before sending output along. This lets us create pipelines that split and merge.

(nesiųsti pranešimų) Prašome prisijungti.

Galvoju, kaip panaudoti kelių procesoriaus branduolių našumą. Reikia drastiškai permąstyti, kaip rašome kodą!

Man pasirodė, kad kilpos gali būti trivialiai lygiagrečios su mano dizainu.

N = 0 .. N = 3×3×3

Jei pasirinktumėte žymėjimo metodą visose gijose su kiekviena N, galėtumėte paleisti visą kilpą vienu ypu.

I am thinking of how to use the performance of multiple CPU cores. It requires a drastic rethinking of how we write code!

It occurred to me that loops could be trivially parallelized with my design.

N = 0 .. N = 3×3×3

If you ran the tick method on all threads with every N, you could run the entire loop in one go.

(nesiųsti pranešimų) Prašome prisijungti.

Sukūriau kelių gijų versiją be Joinable kilpų. Bet šiuo metu darau pertrauką. Man reikia kažkaip pririšti daugiasriegius siūlus prie sujungiamos kilpos. Kai sujungiama kilpa gauna 2 ar daugiau reikšmių, ji toliau apdorojama. Tai leidžia padalinti ir sujungti dujotiekio apdorojimą. Noriu, kad sujungti procesai įvyktų kuo greičiau ir būtų daugiagijai. Mano projekte – kurį dar neįdiegsiu Java – kiekviena gija turi planavimo priemonę, kuri dar kartą patikrina, ką galima pažymėti, ir pažymi ją. Problema yra erkių padalijimas per siūlus, nesunku, jei yra tik vieno lygio žymės. Vienu metu galite pažymėti 8 partijas. Atskirose gijose. Mano pavyzdyje yra įdėtas 3 rinkinių ciklas ir padalintas į dvi užduotis, o tada šios dvi užduotys sujungiamos į vieną užduotį, kad būtų išspausdinti rezultatai. Noriu, kad įdėtos kilpos, atskiros užduotys ir sujungtos užduotys būtų vykdomos paketais. Reikia būdo siųsti lygiagrečias kilpas į senas gijas. Galėtų turėti bendrą kolekciją, vadinamą „tick pool“, kurią tikrina visos gijos. Dabartinis gaminio numeris susietas su gija. Pasirinkau ÷ 8, nes 64 yra 8 kartotinis. Išvalykite partijų skaičių viename siūle.

```

Nors (tiesa) {

Dėl kilpos erkių baseine:

Jei srovė[kilpa] < thisThreadN[kilpa]:

srovė [kilpa] = srovė [kilpa] 1

NewTickersOrResult = Loop.tick()

Jei NewTickersOrResult.isTickers:

„NewTicker“ svetainėje NewTickersOrResult.tickers:

 Dabartinis[kilpa] = gijosSkaičius × newTicker.size() / gijų skaičius

 thisThreadN[kilpa] = gijosSkaičius × newTicker.size() / gijų skaičius gijų skaičius

Pool.extend(NewTickersOrResult.tickers)

Kitas:

Spausdinti (NewTickersOrResult.result)

}

```

I created a multithreading version of this without the Joinable loops. But at this time I am taking a break. I need to somehow tie the multithreading to the joinable loop. When Joinable loop received 2 or more values, it continues processing. This allows a split and merge in pipeline processing. I want joined processes to occur as soon as they can and to be multithreaded. In my design - that I am yet to implement in Java - each thread has a scheduler that rechecks what can be ticked and ticks it. The problem is splitting ticks over threads, it's easy if there is only one level of tickers. You can just tick batches of 8 at a time. In separate threads. My example has a nested loop of 3 collections and a split into two tasks and then those two tasks join into one task to print out the results. I want the nested loops, separate tasks and the joined tasks to be executed in batches. Kind of need a way to send concurrent loops to old threads. Could have a shared collection called the tick pool which is checked by all threads. The current product number is associated with a thread. I picked ÷ 8 due to the 64 being a multiple of 8. Clean number of batches per thread.

```

While (true) {

For loop in tick pool:

If current[loop] < thisThreadN[loop]:

current[loop] = current[loop] + 1

NewTickersOrResult = Loop.tick()

If NewTickersOrResult.isTickers:

For newTicker in NewTickersOrResult.tickers:

 Current[loop] = threadNum × newTicker.size() / threadCount

 thisThreadN[loop] = threadNum × newTicker.size() / threadCount + threadCount

Pool.extend(NewTickersOrResult.tickers)

Else:

Print(NewTickersOrResult.result)

}

```

(nesiųsti pranešimų) Prašome prisijungti.

Turiu problemą, kurią turiu išspręsti. Kuris nesusijęs su lygiagretumu.

Įsivaizduokite, kad turiu įdėtą kilpą, kuri atrodo taip

``` Raštui raidėmis:

Dėl skaičiaus skaičiais:

Spausdinti (raidės numeris)

Simboliams simboliuose:

Spausdinti (raidės simbolis) ```

Noriu, kad šios trys kilpos veiktų vienu metu. Vienas iš būdų yra pasirinkti paleisti funkciją pagal indeksus! Ir apvaliai sujunkite skaičius ir raides. Taigi gauname

A1

A2

Šio metodo problema yra ta, kad kilpos nėra atskirtos. Jie yra viena kilpa, kuri buvo sujungta.

Manau, kad galiu išspręsti šią problemą, kai kolekcijas sudaro kelios kolekcijos. [Raidės, [skaičiai, simboliai] Ir rinkimasis iš kiekvieno subsąrašo apvalios veiklos ir kilpų atskleidimas kaip atskiri objektai.

I have a problem I need to solve. Which isn't related to the parallellism.

Imagine I have a nested loop that looks like this

``` For letter In letters:

For number in numbers:

Print(letter + number)

For symbol in symbols:

Print(letter + symbol) ```

I want these three loops to run concurrently. One approach is to pick the function to run based on the indexes! And merge the numbers and letters together round robin. So we get

A1

A2

The problem with this approach is that the loops aren't separate. They're one loop that has been merged.

I think I can solve this by causing collections to be a multi collection. [Letters, [numbers, symbols] And picking from each sublist round robin and exposing the loops as separate objects.

(nesiųsti pranešimų) Prašome prisijungti.

Supratau savo logikos klaidą. 0 gija yra atsakinga už 0-8 ciklo iteracijas 1 gija yra atsakinga už 8-16 2 gija yra atsakinga už 16-24 Ir taip toliau Šiuo metu aš atlieku ciklo iteracijas netinkamoje gijoje dėl matematinės logikos, kad netvarkau apvyniojimo. Aš naudoju modulio operatorių. Idealiu atveju kiekvienas stulpelis iškviečiamas tik jo diapazone.

I realised my bug in my logic. Thread 0 is responsible for loop iterations 0-8 Thread 1 is responsible for 8-16 Thread 2 is responsible for 16-24 And so on I'm currently executing loop iterations on the wrong thread due to a mathematical logic of not handling wraparound. I use the modulo operator. Ideally each ticker is only called on the thread for its range.

(nesiųsti pranešimų) Prašome prisijungti.

Kalba