Wi-Fi-udvidelse udløser dansk ekstraregning på 100 millioner kroner

Plus19. juli 2021 kl. 11:0666
Wi-Fi-udvidelse udløser dansk ekstraregning på 100 millioner kroner
Illustration: Ingeniøren.
S-togets signalsystem skal flytte sendefrekvens, da 480 MHz i nedre del af 6 GHz skal bruges til ulicenseret Wi-Fi i hele Europa. Det giver en dansk ekstraregning på 100 millioner kroner, fordi S-togets signalsystem bruger mere båndbredde end andre europæiske bybaner.
Artiklen er ældre end 30 dage

Når kalenderen siger den 1. december bliver mængden af radiospektrum afsat til ulicenseret Wi-Fi tæt på fordoblet, når 480 MHz spektrum frigives i den nedre del af 6 GHz-frekvensbåndet. Det øger kapaciteten til trådløse Wi-Fi-netværk markant, men det giver også panderynker og en ekstraregning til Banedanmark på 100 millioner kroner, fordi S-togets signalsystem nu skal flyttes.

Gratis adgang i 30 dage

Tegn et gratis prøveabonnement og få adgang til alt PLUS-indhold på Ing.dk, Version2 og Radar, helt uden binding eller betalingsoplysninger.

Alternativt kan du købe et abonnement
remove_circle
Har du allerede et PLUS-abonnement eller klip?
close

Velkommen til PLUS

Da du er ved at tilmelde dig en gratis prøve beder vi dig hjælpe os med at gøre vores indhold mere relevant for dig, ved at vælge et eller flere emner der interesserer dig.

Vælg mindst et emne *
Du skal vælge en adgangskode til når du fremover skal logge ind på din brugerkonto.
visibility
Dit medlemskab giver adgang
Som medlem af IDA har du gratis adgang til PLUS-indhold, som en del af dit medlemskab. Fortsæt med MitIDA for at aktivere din adgang til indholdet.
Oplever du problemer med login, så skriv til os på websupport@ing.dk
Abonnementsfordele
vpn_key
Fuld adgang til Ing.dk, Version2 og Radar
Fuld digital adgang til PLUS-indhold på Ing.dk, Version2 og Radar, tilgængeligt på din computer, tablet og mobil.
drafts
Kuraterede nyhedsbreve
Det seneste nye fra branchen, leveret til din indbakke.
Adgang til andre medier
Hver måned får du 6 klip, som kan bruges til permanent at låse op for indhold på vores andre medier.
thumb_up
Adgang til debatten
Deltag i debatten med andre kloge læsere.
66 kommentarer.  Hop til debatten
Debatten
Log ind eller opret en bruger for at deltage i debatten.
settingsDebatindstillinger
66
4. august 2021 kl. 17:21

Me.BeginInvoke</p>
<p>Det er noget ganske andet. Når du bruger begininvoke så ryger funktionen på ThreadPoolen.

Jeg tror, du forveksler Delegate.BeginInvoke med Control.BeginInvoke, som Me.BeginInvoke.

Fra min tutorial:

There are two ways of Invoke and BeginInvoke calls - delegate.Invoke/BeginInvoke and control.Invoke/BeginInvoke.</p>
<ul><li>
<p>Delegate.Invoke just executes the methods in the invocation list on the present thread in the same way as normal method calls. Delegate.Invoke is used each time an event is raised. As described previously, RaiseEvent is simply translated to a delegate.Invoke call.</p>
</li>
<li>
<p><strong>Delegate.BeginInvoke needs to return before the job is done. Therefore it makes a System.Threading.ThreadPool.QueueUserWorkItem() call, which graps a thread from the thread pool and uses this for the method if a thread is available. If no thread is available in the pool, the delegate is put in queue until a thread becomes available. The call returns as soon as the job is started on the thread pool thread.</strong></p>
</li>
</ul><p>Det er det, du skriver ovenfor, men som altså henviser til <strong>Delegate</strong>.BeginInvoke.</p>
<ul><li>
<p>Control.Invoke either executes the method(s) in the delegate directly if it is called from the same thread as the one where the control was generated (usually the UI thread), or it sends a message to the message queue of the thread where the control was generated and let the message pump start the method(s). In this case, the method will be executed on the UI thread instead of the thread from which control.Invoke is called so that it can call any methods of a control created on the UI thread (no need to be thread safe). Control.Invoke does not return before the job is done!</p>
</li>
<li>
<p><strong>Control.BeginInvoke is similar to control.Invoke except that it always post a message to the message queue and that it does not wait until the job is done, but returns immediately as soon as the message has been appended to the message queue!</strong>

Det er det sidste, der sker, når man kalder Me.BeginInvoke.

Den interne funktion af Control.Invoke og Control.BeginInvoke er yderst kompleks baseret på "Marchaling", og den er forklaret i flere detaljer i min tutorial i afsnittet Control.Invoke/BeginInvoke, hvor du bl.a. kan se en simplificeret VB oversættelse af funktionen MarshaledInvoke.

Jeg har faktisk brugt en hel del tid på at prøve at komme til bunds i alt dette for at forstå, hvad der rent faktisk sker under motorhjelmen, så jeg synes ikke, at du kan tillade dig at nedgøre min tutorial, som du gjorde med denne bemærkning:

Du har fortalt at du har brugt meget tid på at sætte dig ind i .Net. Det kan jeg ikke tro set i lyset af dine kommentarer i denne tråd.

specielt ikke når du efter eget udsagn ikke har læst den og selv tager fejl.

Vi har haft forskellige definitioner af, hvad vi opfatter som Thread Schedulering, hvilket har givet anledning til en lang diskussion af ThreadPoolen funktion; men mon ikke vi blev enige om den funktion, som du også kan læse ovenfor om Delegate.BeginInvoke, og som jeg derfor har påstået hele tiden?

65
3. august 2021 kl. 22:50

Nu er tasks begrebet efter min tid, da det blev introduceret i .Net 4.0, og jeg har ikke set kode som din beskrevet før; men opnår man noget som helst ved den konstruktion - bortset fra en i mine øjne langt mindre overskuelig kode?

Tasks er et relativt simpelt begreb som også findes i andre ”sprog”. Værdien ligger ikke meget i det vi har snakket om men i at komponere parallel kode vha. tasks + continuations.

Men async/await er en ret genial feature i C# compileren (ved ikke om det findes i VB) som omskriver en funktion til en statemachine sådan at alle de awaits der står i koden i praksis bliver entrypoints for callbacks. Det er mere kompliceret end hvad jeg kan skrive her. Den laver noget lignende med statements yield break og yield return.

I Task klassen <a href="https://docs.microsoft.com/en-us/dotnet/ap..">https://docs.microsoft.co…;. kan man læse følgende:</p>
<p>Because the work performed by a Task object typically executes asynchronously on a thread pool thread rather than synchronously on the main application thread ...

Det er vist pixie-bog versionen. Jeg synes at huske er der er et helt afsnit om tasks på MSDN.

I praksis kan en task scheduleres på alle tråde der ikke har noget at lave. Og når jeg chainer to tasks sammen så bliver det bare til et almindeligt funktionskald fra den ene til den anden.

I det eksempel jeg lavede vil alt kode efter den første await blive kørt på IOCP threads. De er hurtigere at schedulere end almindelige tråde. Som jeg husker det kan IOCP treads i nogle tilfælde blive scheduleret på det interrupt som kommer fra hardwaren men det må du ikke holde mig op på. Det er længe siden. Under alle omstændigheder er det IOCP den mest effektive måde at lave IO på under Windows. Der findes mig bekendt ikke noget lignende på Linux eller FreeBSD så eksekvering af .Net er nok lidt anderledes der.

Læs evt. mere om async/await her: https://devblogs.microsoft.com/premier-developer/dissecting-the-async-methods-in-c/

Men en event fra SerialPort, som f.eks. DataReceived, eksekveres jo også på en thread pool tråd, så hvor er den hastighedsmæssige fordel?

Et hurtigt kig viser at der er er flere context switches når du bruger DataReceived. Der er en schedulering af en intern tråd i SerialThread. Herefter gives data videre til Threadpool.QueueUserWorkItem og således endnu et context switch. Måske er der endnu et. Man skal nok bruge mere end de 5 min. jeg kiggede på koden. Umiddelbart tror jeg også der kan blive problemer med rækkefølge af events når hastigheden bliver høj. Det kan give problemer hvis signaler som CD, RTS, DTS, RI skifter med samme hastighed som datarate.

Hvor i din metode vælger du iøvrigt, hvad SerialPort skal modtage fra transmissionslinjen (Read, ReadByte, ReadChar, ReadExisting, ReadLine, ReadTo), som f.eks COMPort.ReadLine i nedenstående VB eksempel?

Du får bytes. Så må du selv parse data. Men der er vist en StreamReader der kan lave den slags. Det smarte er at den virker på alle bytestreams … filer, netværk, memory-streams, etc.

Me.BeginInvoke

Det er noget ganske andet. Når du bruger begininvoke så ryger funktionen på ThreadPoolen. Det er en måde at lave en synkron funktion til en asynkron funktion. Man skal kun bruge den slags hvis det ikke kan undgås. Det er ineffektivt.

Man kan vælge at bruge .Net relativt naivt og så fungerer det fint til mange ting. Mit gæt er at det er godt nok til 95% af udviklere. Og så kan man gå i dybden og forstå detaljerne. Det er nødvendigt hvis performance er vigtigt. Det er i øvrigt ikke spor anderledes end de fleste andre frameworks/operativ systemer.

Og med dette afslutter jeg min deltagelse her.

64
3. august 2021 kl. 19:10

Her er koden. Jeg har ikke kørt den og ikke skrevet .Net kode i 3 år så der er sikkert småfejl men konceptet er sikkert.
...

Nu er tasks begrebet efter min tid, da det blev introduceret i .Net 4.0, og jeg har ikke set kode som din beskrevet før; men opnår man noget som helst ved den konstruktion - bortset fra en i mine øjne langt mindre overskuelig kode?

I Task klassen https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task?view=net-5.0 kan man læse følgende:

Because the work performed by a Task object typically executes asynchronously on a thread pool thread rather than synchronously on the main application thread ...

Men en event fra SerialPort, som f.eks. DataReceived, eksekveres jo også på en thread pool tråd, så hvor er den hastighedsmæssige fordel?

Hvor i din metode vælger du iøvrigt, hvad SerialPort skal modtage fra transmissionslinjen (Read, ReadByte, ReadChar, ReadExisting, ReadLine, ReadTo), som f.eks COMPort.ReadLine i nedenstående VB eksempel?

Public Delegate Sub StringSubPointer(ByVal Buffer As String)</p>
<pre><code> Dim WithEvents COMPort As New SerialPort

Private Sub Receiver(ByVal sender As Object, _
ByVal e As SerialDataReceivedEventArgs) Handles COMPort.DataReceived
Me.BeginInvoke(New StringSubPointer(AddressOf Display), COMPort.ReadLine)
End Sub

Private Sub Display(ByVal Buffer As String)
Received.AppendText(Buffer)
End Sub
</code></pre>
<p>

Threadpool:

Men grundlæggende er algoritmen når man kalder QueueUserWorkItem:</p>
<p>Er der en idle thread i threadpoolen? Hvis der er så giv opgaven til samme thread. Ellers smid opgaven i køen.</p>
<p>Når en thread afslutter kørsel af en opgave tages næste opgave fra køen. Der er ingen garanti for rækkefølge.</p>
<p>Når en opgave har ventet længe nok i køen startes en ny thread op (det er mere komplekst end beskrevet her, men bliver for langt at skrive mere).

Helt enig.

63
3. august 2021 kl. 17:28

Du foretager stadig en fuldstændig grotesk og vanvittig sammenligning mellem æbler og pærer. SerialPort klassen er beregnet til at håndtere en del af lag 1 og 2 i OSI's 7-lags model for datakommunikation ved hjælp af en UART - herunder opsætning af de nødvendige parametre som f.eks. bitrate, antallet af data- og stopbits, evt. paritet og evt. flowcontrol. ReadAsync har ingen funktionalitet til den slags og kan derfor ikke bruges i stedet.

Her er koden. Jeg har ikke kørt den og ikke skrevet .Net kode i 3 år så der er sikkert småfejl men konceptet er sikkert.

using System;</p>
<p>using System.IO.Ports;</p>
<p>using System.Threading.Tasks;</p>
<p>public class Program {
public static void Main() {
SerialPort port = new SerialPort();
port.BaudRate = 2400;
Task readerTask = ReadPort(port);
readerTask.Wait();
}</p>
<p>public static async Task ReadPort(SerialPort port) {
byte[] buffer = new byte[0x1000];
int numRead;
while ((numRead = await port.BaseStream.ReadAsync(buffer, 0, buffer.Length)) > 0) {
Console.WriteLine("{0} bytes read", numRead);
}
}
}

Der er ingen formateringsmekanisme på ing.dk ... derfor er det lidt svært at læse uden at kopiere koden ind i en editor.

Enig; men det, der sker, hvis flere task blokkerer, er, at man kan nå loftet for det maksimale antal tråde i poolen, så der ikke er en ledig tråd til næste job (event), som dermed kommer til et vente i køen.

Men hele ideen er at man skal lade være med at skrive kode der blokerer.

Jeg opfatter den bemærkning som ".. for Threads at blive scheduleret", hvilket er forkert. Da jeg protesterede, og du åbenbart fik læst lidt på lektien, reducerede du det da også til:

Jeg er naturligvis ked af hvis du forstod min kommentar forkert. Men scheduleret betyder mange ting … også i en parallelprogrammeringskontekst.

Du mangler så stadig at fortælle mig, hvad den "smule" er. En kø, som bruges, hvis der ikke er tråde nok, er i mine øjne ikke en schedulering.

Som jeg har skrevet i tidligere indlæg har Microsoft ændret lidt på heuristikken for opstart af threads gennem årene. Men grundlæggende er algoritmen når man kalder QueueUserWorkItem:

  1. Er der en idle thread i threadpoolen? Hvis der er så giv opgaven til samme thread. Ellers smid opgaven i køen.
  2. Når en thread afslutter kørsel af en opgave tages næste opgave fra køen. Der er ingen garanti for rækkefølge.
  3. Når en opgave har ventet længe nok i køen startes en ny thread op (det er mere komplekst end beskrevet her, men bliver for langt at skrive mere).

Ovenstående er schedulering men ikke preemptiv schedulering.

Rigtigt; men async/await blev først indført fra .Net 4.5, og der er stadig (5.0) ingen support for async i SerialPort klassen, som f.eks. en ReadAsync metode som supplement til Read, så det er ikke nogen option, hvis man vil bruge den klasse og hvis ikke - hvad er så meningen med at bruge .Net?

Som beskrevet i koden ovenfor er der support for ReadAsync når man tager fat i BaseStream propertien. async/await er bare syntaktisk sukker ovenpå BeginRead/EndRead Det hele kan laves med BeginRead/EndRead som har været der siden .Net 1.1 Her er Microsofts implementation af ReadAsync:

public virtual Task ReadAsync(Byte[] buffer, int offset, int count, CancellationToken cancellationToken)
{
return cancellationToken.IsCancellationRequested
? Task.FromCancellation(cancellationToken)
: BeginEndReadAsync(buffer, offset, count);
}</p>
<pre><code> private Task<Int32> BeginEndReadAsync(Byte[] buffer, Int32 offset, Int32 count)
{
return TaskFactory<Int32>.FromAsyncTrim(
this, new ReadWriteParameters { Buffer = buffer, Offset = offset, Count = count },
(stream, args, callback, state) => stream.BeginRead(args.Buffer, args.Offset, args.Count, callback, state), // cached by compiler
(stream, asyncResult) => stream.EndRead(asyncResult));
}
</code></pre>
<p>

Som du kan se kalder ReadAsync bare videre ned i BeginRead/EndRead ...

Både og. Ved cooperative multithreading frigiver du ikke CPU'en, før jobbet er fuldført, eller du har gemt din egen kopi af data; men hvis programmøren dummer sig, er der selvfølgelig ingen garanti for, at data ikke kan blive overskrevet.
Preemptive multithreading er hamrende ineffektivt, men idiotsikkert.

Hvis man ikke kan finde ud af hvornår ens kode venter, så kan man heller ikke finde ud af at bruge de synkroniseringsprimitiver der er nødvendige for parallelprogrammering. Som jeg skrev ovenfor er problemer med coorperativ multitasking at koden nemt hakkes op i unaturlige bidder. Heldigvis er CPU’er hurtige nok i dag til at det er et minimalt problem fordi der typisk er ressourcer til at kører meget store bidder uden at det rammer andre.

Jeg er spændt på hvor længe I 2 kan blive ved uden at blive enige.

Det er sikkert svært at forstå hvorfor jeg stadigvæk hænger på. Jeg valgte at gøre det i denne omgang.

62
3. august 2021 kl. 10:50

Du må korrigere mig hvis min opfattelse af det citerede er forkert. I din beskrivelse af ulemper ved preemptive multitasking skriver du:</p>
<p>"there is no guarantee that a subroutine or function has finished the use of some data before another part of the program can change these data"</p>
<p>Og derved forstår jeg at du mener det modsatte må være tilfælde ved cooperative multitasking.

Både og. Ved cooperative multithreading frigiver du ikke CPU'en, før jobbet er fuldført, eller du har gemt din egen kopi af data; men hvis programmøren dummer sig, er der selvfølgelig ingen garanti for, at data ikke kan blive overskrevet.

Preemptive multithreading er hamrende ineffektivt, men idiotsikkert.

61
3. august 2021 kl. 10:41

Prøv at kigge på hvordan BeginRead/EndRead virker. Eller endnu bedre så kig på ReadAsync som bruger async/await funktionaliteten i C#. Der er også funktioner til write.

Du foretager stadig en fuldstændig grotesk og vanvittig sammenligning mellem æbler og pærer. SerialPort klassen er beregnet til at håndtere en del af lag 1 og 2 i OSI's 7-lags model for datakommunikation ved hjælp af en UART - herunder opsætning af de nødvendige parametre som f.eks. bitrate, antallet af data- og stopbits, evt. paritet og evt. flowcontrol. ReadAsync har ingen funktionalitet til den slags og kan derfor ikke bruges i stedet.

Threadpoolen er beregnet til korte opgaver. Det er blot en kø og en pool af tasks. Det er ikke meningen at man skal blokere inde i en task der kører på threadpoolen.

Enig; men det, der sker, hvis flere task blokkerer, er, at man kan nå loftet for det maksimale antal tråde i poolen, så der ikke er en ledig tråd til næste job (event), som dermed kommer til et vente i køen. Det blokkerer dog ikke andre tråde, hvilket ville ske, hvis en thread pool tråd ikke blev preempted. En uendelig sløjfe i en thread pool tråd reducerer bare antallet at tråde i poolen med 1 og sænker hastigheden, fordi man spilder 10 eller 15 ms hver gang, tråden kører.

Set fra threadpoolens synspunkt så kører tasken til den er færdig. Naturligvis kan Windows preempte en task men det lægger threadpoolen ikke mærke til.

Ja, for det er netop ikke thread poolen, der foretager (preemptive) thread schedulering.

Du har fortalt at du har brugt meget tid på at sætte dig ind i .Net. Det kan jeg ikke tro set i lyset af dine kommentarer i denne tråd.

Ja, ja. Her er, hvad du først skrev om thread poolen:

Hele ideen med ThreadPoolen er at have et sted for Tasks at blive scheduleret.

Jeg opfatter den bemærkning som ".. for Threads at blive scheduleret", hvilket er forkert. Da jeg protesterede, og du åbenbart fik læst lidt på lektien, reducerede du det da også til:

Der foregår en smule scheduling men ikke preemptive scheduling.

Du mangler så stadig at fortælle mig, hvad den "smule" er. En kø, som bruges, hvis der ikke er tråde nok, er i mine øjne ikke en schedulering.

Det fine ved at have skrevet den tutorial er, at ingen kan beskylde mig for at ændre mening siden 2010. Er der fejl i den eller noget, der bør ændres eller evt. formuleres anderledes, hører jeg gerne om det; men det skal være veldokumentet med links. Microsoft kan jo have lavet en del ændringer siden 2.0 (og 3.5 RTM, som var ubrugelig til mit formål, da stort set intet virkede i SerialPort).

I praksis er det en form for cooperativ multitasking man bruger. Det er meget mere effektivt at skifte opgave på veldefinerede steder end når kernen beslutter at kode har kørt længe nok. Fx. er det ødelæggende hvis en thread bliver preempted mens den holder en kritisk ressouce. Derfor har man opfundet ting så som critical section etc. men det har vist sig ikke at være effektivt nok Og med moderne CPU’er er der cycles nok til at det ikke ødelægger koden at lave cooperativ multitasking. Og med async/await funktionalitet i C# kommer koden næsten til at ligne traditionel kode.

Rigtigt; men async/await blev først indført fra .Net 4.5, og der er stadig (5.0) ingen support for async i SerialPort klassen, som f.eks. en ReadAsync metode som supplement til Read, så det er ikke nogen option, hvis man vil bruge den klasse og hvis ikke - hvad er så meningen med at bruge .Net?

Alas, det er nok ikke nødvendigt set i lyset af at processkontrol sikkert ikke har behov for at bruge hver eneste cycle i CPU'en til noget fornuftigt.

Jo, det kan jeg love dig for, for det drejer sig både om pålidelighed og pris og nogle gange også om strømforbrug, så den mindste og langsomste processor, der kan klare opgaven, er ofte den mest optimale.

Langt det meste proceskontrol er baseret på en soft-PLC, som er et interpreterende system, der gør det muligt at skrive koden som logiske funktioner (AND, OR etc.) og evt. rent grafisk med symboler for gates og andet, og her benytter man ikke en task for hver hændelse, men typisk en kø af interne procesværdier, som er sat op til beregning af en hændelse i systemet (i optimal rækkefølge så selv en kanttrigget D-FlipFlop baseret på gates virker). Det ved jeg alt om, efter som det var mig, der i sin tid skrev den hændelsesstyrede soft-PLC til Søren T. Lyngsø's Stella system.

Og naturligvis kan det også håndtere et par serielporte ... man skal bare vælge de rigtige API'er til opgaven.

Problemet er bare, at man ikke har noget valg, med mindre man vil skrive sine egne klasser og evt. også egne hardwaredrivere!

60
2. august 2021 kl. 14:39

Jeg er spændt på hvor længe I 2 kan blive ved uden at blive enige.

59
1. august 2021 kl. 12:26

Hvad kunne jeg ellers gøre, hvis jeg vil bruge SerialPort - lade være med at sætte WithEvents og så polle, hvilket er særdeles ineffektivt? Der er da ikke andre muligheder.

Prøv at kigge på hvordan BeginRead/EndRead virker. Eller endnu bedre så kig på ReadAsync som bruger async/await funktionaliteten i C#. Der er også funktioner til write.

Hvilken anden scheduling har thread-pool threads så? Hvis ikke en thread-pool tråd kan afbrydes af en timer på samme måde som andre tråde, vil den jo kunne fortsætte i uendelig tid og dermed blokkere Windows, da man ikke kan regne med cooperative programmering.

Som sagt: Threadpoolen er beregnet til korte opgaver. Det er blot en kø og en pool af tasks. Det er ikke meningen at man skal blokere inde i en task der kører på threadpoolen. Set fra threadpoolens synspunkt så kører tasken til den er færdig. Naturligvis kan Windows preempte en task men det lægger threadpoolen ikke mærke til.

Det er for nemt at skrive. Du bør komme med en link, der besvarer ovenstående spørgsmål. Ikke ét eneste sted incl. dem, jeg har linket til, har jeg set, at ThreadPoolen skulle foretage nogen som helst form for schedulering. Det vil også være særdeles ulogisk, at Microsoft ikke bare skulle opfatte thread-pool tråde som alle andre tråde og benytte samme preemptive multitasking.

Jeg er ikke skolelærer. Min viden om dette område bygger på mange års erfaring. Jeg har ikke nogen litteraturliste for folk der vil sætte sig ind i området. Du har fortalt at du har brugt meget tid på at sætte dig ind i .Net. Det kan jeg ikke tro set i lyset af dine kommentarer i denne tråd.

Det kommer godt nok an på, om du har kerner nok til hver eneste task. Har du ikke det, er multithreading absolut nødvendigt ved f.eks. proceskontrol og alle former for kommunikation.

Nej. I praksis er det en form for cooperativ multitasking man bruger. Det er meget mere effektivt at skifte opgave på veldefinerede steder end når kernen beslutter at kode har kørt længe nok. Fx. er det ødelæggende hvis en thread bliver preempted mens den holder en kritisk ressouce. Derfor har man opfundet ting så som critical section etc. men det har vist sig ikke at være effektivt nok Og med moderne CPU’er er der cycles nok til at det ikke ødelægger koden at lave cooperativ multitasking. Og med async/await funktionalitet i C# kommer koden næsten til at ligne traditionel kode.

Vrøvl. Hvordan vil du lave parallelprogrammering på en enkeltkernet processor, som er det, der langt oftest bruges i min branche?

Vrøvl selv. Brug noget tid på at catche op på moderne parallelprogrammering. Som sagt er det i praksis coorperativ multitasking. Processkontrol kan fint håndteres på single core processorer med moderne principper. Alas, det er nok ikke nødvendigt set i lyset af at processkontrol sikkert ikke har behov for at bruge hver eneste cycle i CPU'en til noget fornuftigt. Den 8-bit Atmel processer der sidder på mine Arduino boards synes kraftfuld nok til de fleste ting.

Ja, selvfølgelig; men hele denne diskussion er gået på SerialPort, og den bruges næppe i sådanne multikernede systemer.

Ja ... men du brokkede dig over hvordan .Net var konstrueret. Det er designet til at kunne eksekvere massivt parallelle opgaver effektivt. Og naturligvis kan det også håndtere et par serielporte ... man skal bare vælge de rigtige API'er til opgaven. Det ændrer dog ikke ved at der givetvis er fucket op nogle steder i implementeringen af SerialPort på .Net. Det er givetvis ikke den del af .Net der bruges mest. Når jeg kigger på koden så synes der at være nogle raceconditions men det er ikke noget jeg har gravet dybt i …

58
30. juli 2021 kl. 21:30

Det har da absolut intet med synkron kommunikation at gøre!</p>
<p>Det har jeg aldrig sagt.

Du skrev:

Men hvis du kigger på din fine SerialPort classe, så er der både et synkront interface, et asynkront interface, et event drevent interface og et async/await interface (det kom dog sikkert efter du skrev din kode). <strong>Du valgte det event baserede som er det langsomste.</strong>

Hvad kunne jeg ellers gøre, hvis jeg vil bruge SerialPort - lade være med at sætte WithEvents og så polle, hvilket er særdeles ineffektivt? Der er da ikke andre muligheder.

Der foregår en smule scheduling men ikke preemptive scheduling.

Hvilken anden scheduling har thread-pool threads så? Hvis ikke en thread-pool tråd kan afbrydes af en timer på samme måde som andre tråde, vil den jo kunne fortsætte i uendelig tid og dermed blokkere Windows, da man ikke kan regne med cooperative programmering.

Hvis du vil vide mere må du læse dig til det.

Det er for nemt at skrive. Du bør komme med en link, der besvarer ovenstående spørgsmål. Ikke ét eneste sted incl. dem, jeg har linket til, har jeg set, at ThreadPoolen skulle foretage nogen som helst form for schedulering. Det vil også være særdeles ulogisk, at Microsoft ikke bare skulle opfatte thread-pool tråde som alle andre tråde og benytte samme preemptive multitasking.

Det jeg skrev var at det underliggende Win32 API er specificeret til 256000 baud.

Du har ikke en chance for at køre 256 kbit/s uden en meget stor FIFO, så uden en sådan specifikation er den grænse det rene nonsense; men Microsoft her heller aldrig forstået den serielle port, hvilket deres implementering også klart beviser. Alene det, at de åbenbart taler om baud og ikke bit/s, viser, at de ikke har meget hardwarekendskab. Max-i er et eksempel på en feltbus, som har en fast baudrate, men ingen fast bitrate, og ved Manchester kodning er baudraten det dobbelte af bitraten.

Det er længe siden at man fandt ud af at threads ikke er noget optimalt paradigme når man laver highperformance kode.

Det kommer godt nok an på, om du har kerner nok til hver eneste task. Har du ikke det, er multithreading absolut nødvendigt ved f.eks. proceskontrol og alle former for kommunikation.

I denne diskussion er du kommet med statements som viser at du er out of touch med moderne parallelprogrammering.

Vrøvl. Hvordan vil du lave parallelprogrammering på en enkeltkernet processor, som er det, der langt oftest bruges i min branche? Skal det gå stærkt, bruger jeg FPGA'er, hvilket Max-i feltbussen er baseret på, og det er parallelprogrammering i yderste konsekvens med over 5900 "kerner" (gates) for Max-i.

Men der er ganske enkelt meget stor forskel på at holde et antal UARTS fodret med data og på at holde 256 kerner i computer igang med at lave noget fornuftigt når man har brug for meget performance.

Ja, selvfølgelig; men hele denne diskussion er gået på SerialPort, og den bruges næppe i sådanne multikernede systemer.

Og set i lyset af at Moores lov har givet os CPU’er hvor max clock frekvens er ca. 5GHz og hvor max instruction level parallelism synes at ligge omkrig 8, så er multicore CPU og massiv parallelisme vejen frem.

Plus stærkt forøget effektivitet. Bare at gøre systemerne større er en håbløs vej, som kun giver små forbedringer for astronomiske omkostninger til mindre og mindre geometrier, som kun kan produceres på få fabrikker med deraf følgende sårbarhed.

57
30. juli 2021 kl. 19:42

Det har da absolut intet med synkron kommunikation at gøre!

Det har jeg aldrig sagt. Jeg har sagt at interfacet var asynkront. I .Net (og mange andre) regi betyder det at når du fx. kalder BeginRead så returnerer den altid med det samme. Den venter aldrig. Når data er klar så kalder systemet den callback funktion som du angiver ved BeginRead. Herefter skal du kalde EndRead for at få data. På den måde venter din kode aldrig og unødvendige task switches fjernes.

Du kender åbenbart ikke forskel på synkron og asynkron kommunikation!

Selvfølgeligt gør jeg det. Men jeg bøjer mig for at du er eksperten på det område. Det er ganske enkelt 30 år siden jeg har rodet med den slags.

Det er vel et spørgsmål om ord. Alt i .Net er ganske rigtigt ikke eventdrevet, og ved SerialPort kan man selv vælge ved i VB at erklære eller ikke-erklære WithEvents:

Selvfølgeligt er det ikke blot et spørgsmål om ord. Specielt ikke når din største anke er noget om task switches.

Hvordan kan de to udsagn forstås, som at task schedule foregår i thread poolen, som du bliver ved med at hævde?

Der foregår en smule scheduling men ikke preemptive scheduling. Microsoft har ændret det flere gange men grundlæggende er ThreadPoolen en queue af opgaver der skal udføres og et antal threads. Når du kalder QueueUserWorkItem så ryger opgaven i køen med mindre en thread er idle. Køen tømmes for arbejde i en ikke-defineret rækkefølge. Når threadpoolen beslutter at der er brug for flere threads så laves nye. Det er ikke nogen specielt intelligent mekanisme men den er nem at bruge. Hvis du vil vide mere må du læse dig til det.

Der er ikke noget, der kører uden for specifikationerne selv ved 4 Mbit/s, for det problem klares af en stor FIFO i UART'en

Det jeg skrev var at det underliggende Win32 API er specificeret til 256000 baud. Den kan jeg se i dokumentationen. Det er således ikke sikkert at Microsoft har brugt krudt på at teste eller optimere koden til højere hastigheder. Jeg kan dog sige at jeg fint har kørt 256000 uden nogen problemer.

En task er et job; men for at køre flere job parallelt behøver du enten flere CPU-kerner eller flere tråde, og som jeg kan se det, styrer System.Treading ikke flere kerner, så reelt set må threads og tasks være det samme i denne sammenhæng.

Det er slet ikke det samme. Det er to forskellige paradigmer. Det er længe siden at man fandt ud af at threads ikke er noget optimalt paradigme når man laver highperformance kode.

Jeg har beskæftiget mig med multitasking/multithreading og eventstyring de sidste over 40 år i forbindelse med elektronisk proceskontrol og skrev bl.a. den eventstyrede PLC fortolker til Søren T. Lyngsø's Stella system, så det ved jeg ganske meget om. Den lidt nedladende betegnelse "vaskemaskineprogrammering", som jeg og mange andre ligesindede benytter, henviser til programmer, som ikke er multitrådede eller eventstyrede og derfor blot eksekveres fra en ende af, som en simpel mekanisk vaskemaskinestyring.

Verden er ligeglad. I denne diskussion er du kommet med statements som viser at du er out of touch med moderne parallelprogrammering. Det er slet ikke det samme som at din kode ikke virker eller er dårlig. Men der er ganske enkelt meget stor forskel på at holde et antal UARTS fodret med data og på at holde 256 kerner i computer igang med at lave noget fornuftigt når man har brug for meget performance. Og set i lyset af at Moores lov har givet os CPU’er hvor max clock frekvens er ca. 5GHz og hvor max instruction level parallelism synes at ligge omkrig 8, så er multicore CPU og massiv parallelisme vejen frem.

Som kuriosum har jeg skrevet drivere til at seriel kommunikation med PLC’er i tidernes morgen – det er 30 år siden. Jeg har kodet direkte på UART’er og var lykkelig da UART’er i PC’en fik 16 bytes rx/tx buffers. Men det er længe siden og jeg skal hverden kalde mig expert i PLC’er eller synkron/asynkron serielkommunikation.

Siden har jeg bl.a. bygget massivt parallelle systemer der kunne scalere til at udnytte alle kerne i mange-core+mange CPU maskiner. Jeg ved en hel del om den slags. Pludseligt skal man forstå deltaljer om CPU’er som ellers var ligegyldige i gamle dage. Jeg er sikker på at verden også er ligeglad med min karriere.

56
30. juli 2021 kl. 12:42

<em>Der er ikke spor at det synkrone interface, som du nævner, så hvor får du det fra?</em></p>
<p>SerialPort.BaseStream … her har du adgang til alle de forskellige programmeringsmodeller. Hvis du kigger på source koden til SerialPort så vil du se at den blot kalder videre til den SerialStream som du kan få fat i gennem BaseStream propertien.

Det har da absolut intet med synkron kommunikation at gøre! Du kender åbenbart ikke forskel på synkron og asynkron kommunikation! Hvis SerialPort skulle understøtte synkron kommunikation, skulle der bl.a. være metoder til generering og detektering af flag og bitstuffing, så f.eks. HDLC https://en.wikipedia.org/wiki/High-Level_Data_Link_Control var understøttet. Hvordan vil du ellers generere synkron kommunikation, med mindre du som i Max-i kan gøre det hardwaremæssigt?

Selvfølgelig sender SerialPort data videre i en (16-bit) stream; men desværre efter at statusbyten er strippet fra, så den vitale synkronisering mellem data of flag går tabt og ikke kan gendannes - gud bedre det. Det er derfor, jeg har været nødt til at anvende en UART i wide-mode.

Classen SerialPort er designet som event dreven. Ligesom en række andre .Net classer. Det er ikke det samme som at .Net er event drevet. Jeg har skrevet .Net programmer på adskillige hundrede tusinde linjer kode der ikke har et eneste event.

Det er vel et spørgsmål om ord. Alt i .Net er ganske rigtigt ikke eventdrevet, og ved SerialPort kan man selv vælge ved i VB at erklære eller ikke-erklære WithEvents:

Dim <strong>WithEvents</strong> NameOfSerialPort As New System.IO.Ports.SerialPort

Hvis man kun bruger SerialPort i et pollet system og derfor ikke har brug for automatisk respons på nogen af de 3 events, kan det udelades; hvilket også er forklaret udførligt i min tutorial. Hvis mine kortfattede indlæg her kan mistolkes, vil jeg henvise til min fulde mening der.

<em>Den [thread poolen] er et sted, hvorfra man kan hente "ready-made" tråde.</em></p>
<p>Nej. Det er ikke et sted hvor du kan hente ready-made tråde. ThreadPoolen er en mekanisme der kan køre ”opgaver” (aka tasks) asynkront.

Tja. Microsoft skriver selv følgende om ThreadPool Class (min ovenstående link) og om System.Threading Namespace https://docs.microsoft.com/en-us/dotnet/api/system.threading?view=net-5.0 :

Provides a pool of threads <strong>that can be used to execute tasks, post work items, process asynchronous I/O, wait on behalf of other threads, and process timers</strong>.</p>
<p>. . .</p>
<p>Provides classes and interfaces that enable multithreaded programming. In addition to classes for synchronizing thread activities and access to data (Mutex, Monitor, Interlocked, AutoResetEvent, and so on), <strong>this namespace includes a ThreadPool class that allows you to use a pool of system-supplied threads</strong>, and a Timer class that executes callback methods on thread pool threads.

Bemærk den fremhæved tekst! Begge udsagn opfatter jeg som en gang "ready-made", "system-supplied" tråde (default 25 stk.), som kan hentes fra thread poolen og bruges til forskellige formål og så returneres, når man ikke længere har brug for dem. SerialPort bruger f.eks. disse tråde til de 3 events, og ovenstående link bruger én til at skrive "Hello from the thread pool.". Hvordan kan de to udsagn forstås, som at task schedule foregår i thread poolen, som du bliver ved med at hævde? Man kan vel sagtens bruge multithreading uden at erklære ThreadPool klassen, ligesom man vel heller ikke behøver at erklære Timer klassen, hvis man ikke har brug for timere(?), og hvis det er tilfældet, kan thread schedule ialtfald ikke foregå i thread poolen. Hvis det virkelig var rigtigt, at thread-poolen er det sted, hvor alle tråde bliver scheduleret, hvordan forklarer du så, at UI tråde har højere prioritet end ThreadPool tråde?

Du ejer ikke tråden. Du får blot kørt din kode.

Rigtigt. Det er jo også det, jeg har påstået hele tiden.

Jeg kan se i Win32 dokumentationen at hele serial port API’et kun er specificeret på til 256000 baud. Du kører således udenfor specs.

Der er ikke noget, der kører uden for specifikationerne selv ved 4 Mbit/s, for det problem klares af en stor FIFO i UART'en. Med en interrupt responstid på op til 1 ms, kan du ikke garantere at køre meget hurtigere end ca. 9,6 kbit/s uden en FIFO. Når Microsoft nævner 256 kbit/s - ikke kbaud, som er det reciprokke af den korteste puls på linjen og derfor er udtryk for den nødvendige båndbredde, er det nok fordi, de og andre ikke har kunnet få det til at køre hurtigere; men en stor del af den tid, jeg har brugt på at grave mig ned i .Net, er primært for at finde ud af, hvor man kan optimere, og det har været til glæde for både mig og Texas Instruments, der ellers ikke ville være nået i mål med de løsningsmetoder, Microsoft og andre har beskrevet.

At køre serial port kommunikation hurtigere synes ikke at være at problem det er værd at lægge mange ressourcer i fra Microsoft side.

Nej, Microsoft har tværtimod i mange år prøvet at gøre alt for at slippe af med asynkron kommunikation; men talrige enheder som f.eks. GPS modtagere, mange industristyringer og små mikrocomputere bruger den stadig, og den er også en interfacemulighed til min feltbus Max-i, der iøvrigt anvender synkron kommunikation på selve bussen vha. en speciel hardwarekodning, der gør flag og bitstuffing overflødig.

System.Threading.Tasks … det er noget ganske andet System.Threading … det handler ikke længere om threads men om tasks.

En task er et job; men for at køre flere job parallelt behøver du enten flere CPU-kerner eller flere tråde, og som jeg kan se det, styrer System.Treading ikke flere kerner, så reelt set må threads og tasks være det samme i denne sammenhæng.

Hele ideen er at user kode i princippet aldrig venter på noget. Når man ønsker at køre kode efter noget er indtruffet (fx at data er modtaget fra netværket eller sendt), så giver man en stump kode til det underliggende system og den stump kode bliver så kørt efter. Lidt i stil med de events du har rodet med, men bare med mange flere muligheder for at sætte ting sammen. Jeg kan se at Hans Henrik Løvengreen (som var en fantastisk underviser da han underviste undertegnede i 1990) har en smule om det i sit kursus om concurrent programming på DTU.

Jeg har beskæftiget mig med multitasking/multithreading og eventstyring de sidste over 40 år i forbindelse med elektronisk proceskontrol og skrev bl.a. den eventstyrede PLC fortolker til Søren T. Lyngsø's Stella system, så det ved jeg ganske meget om. Den lidt nedladende betegnelse "vaskemaskineprogrammering", som jeg og mange andre ligesindede benytter, henviser til programmer, som ikke er multitrådede eller eventstyrede og derfor blot eksekveres fra en ende af, som en simpel mekanisk vaskemaskinestyring.

55
30. juli 2021 kl. 09:47

Det gør de da ikke. .Net SerialPort er eventdrevet baseret på tråde, hvilket også fremgår klart af min tutorial, …

Jeg har naturligvis ikke læst din tutorial. Når jeg læser dine indlæg her så er det klart at du render med en halv vind på dette område.

Der er ikke spor at det synkrone interface, som du nævner, så hvor får du det fra?

SerialPort.BaseStream … her har du adgang til alle de forskellige programmeringsmodeller. Hvis du kigger på source koden til SerialPort så vil du se at den blot kalder videre til den SerialStream som du kan få fat i gennem BaseStream propertien.

Når jeg er efter dig her så er det fordi du kommer med et blanket statement om .Net og Windows. Du gør det efter at have løftet en flig af et kæmpe system og åbenlyst uden at have sat dig ordentligt ind i tingene. Jeg er i øvrigt hverken specielt forelsket i .Net eller Windows.

<em>.Net er ikke event styret.</em>
Så forklar mig lige hvad de 3 events DataReceived, ErrorReceived og PinChanged så bruges til!

Classen SerialPort er designet som event dreven. Ligesom en række andre .Net classer. Det er ikke det samme som at .Net er event drevet. Jeg har skrevet .Net programmer på adskillige hundrede tusinde linjer kode der ikke har et eneste event.

<em>Nej, hele ideen med ThreadPoolen er at kode der kører der.</em></p>
<p>Dit vrøvl bliver altså ikke mere rigtigt af, at du gentager det. Der er da ingen kode, der kører på TreadPoolen. Den er et sted, hvorfra man kan hente "ready-made" tråde.

Nej. Det er ikke et sted hvor du kan hente ready-made tråde. ThreadPoolen er en mekanisme der kan køre ”opgaver” (aka tasks) asynkront. Du ejer ikke tråden. Du får blot kørt din kode. Guidance fra Microsoft er også at kode der kører på threadpoolen ikke må blokere (aka vente) fordi det midlertidigt kan skabe deadlocks. For at undgå permanente deadlocks er der så en mekanisme der gør threadpoolen større efter nogen tid hvis opgaver (aka tasks) har ventet for længe på at blive startet.

Den måde mekanismen til at allokere flere tråde til threadpoolen er lavet gør den uegnet til et sted hvor man kan hente ”ready-made” tråde. Mekanismen er i øvrigt ikke veldefineret i nyere versioner af .Net og derfor slet ikke velegnet til tidkritiske ting.

Jeg er da fuldstændig klar over, at man bare kan skrive sine egne drivere og kommunikere direkte med IC-kredsen, eller lave et reflection hack, så man får fat i "handle" til den åbnede port og så gøre det den vej, som jeg var tvunget til for at sætte min MaxLinear UART i wide-mode; men hvis man vil lave ordentlige .Net programmer, er det .Net hele vejen og ikke specialdesignede løsninger og mystiske krumspring. Min tag i MSDN er:

Men der er ingen der beder dig om at lave din egen driver eller reflection. Der er adgang til langt mere funktionalitet end det du bruger hvis man blot kigger sig omkring. Hvorvidt det er nok til dit eksempel ved jeg ikke. Jeg kan se i Win32 dokumentationen at hele serial port API’et kun er specificeret på til 256000 baud. Du kører således udenfor specs. At køre serial port kommunikation hurtigere synes ikke at være at problem det er værd at lægge mange ressourcer i fra Microsoft side.

Nå, nu begynder du måske at indrømme, at du fik skrevet noget forfærdelig sludder om thread poolen i dit sidste indlæg

Nej. Jeg tilkendegav at du havde skrevet noget rigtigt. Det gør jeg gerne igen når det sker og det er signifikant.

<em>Men her skal jeg huske at gøre opmærksom på at det er den slags tasks der findes i System.Threading.Tasks.</em></p>
<p>Ja, hvad ellers? System.Threading har da hele tiden været grundlaget for SerialPort klassen og er det stadig, som 5.0 eksemplet ovenfor også klart viser:

System.Threading.Tasks … det er noget ganske andet System.Threading … det handler ikke længere om threads men om tasks. Skiftet fra at komponere paralleliseret kode vha. threads til tasks er ikke et paradigme unik for .Net men kendt fra en række områder. På samme måde forsøger man at undgå brug af semaphorer, mutexer, monitors men i stedet give programmøren et række mere abstrakte primitiver at arbejde med. Ideen er at det øger scalabiliteten af koden samt reducerer antallet af fejl.

Hele ideen er at user kode i princippet aldrig venter på noget. Når man ønsker at køre kode efter noget er indtruffet (fx at data er modtaget fra netværket eller sendt), så giver man en stump kode til det underliggende system og den stump kode bliver så kørt efter. Lidt i stil med de events du har rodet med, men bare med mange flere muligheder for at sætte ting sammen. Jeg kan se at Hans Henrik Løvengreen (som var en fantastisk underviser da han underviste undertegnede i 1990) har en smule om det i sit kursus om concurrent programming på DTU.

54
29. juli 2021 kl. 13:22

Nu bliver det sgu helt Trump lignende. Lige ovenover skrev du:</p>
<p>… men går via .Net's preemptive multitasking, som kræver mindst ét task switch.</p>
<p>Hvilket meget godt viser at dine argumenter er helt udenfor skiven og ændrer sig fra indlæg til indlæg.

Det gør de da ikke. .Net SerialPort er eventdrevet baseret på tråde, hvilket også fremgår klart af min tutorial, og min mening om den sag har ikke ændret sig siden 2010. At de tråde så måske er Win32's egne, ændrer da intet ved det; men det er måske endnu et forsøg på at gå efter manden i stedet for bolden?

.Net er er ikke event drevet. Der er nogle classer der er har event API’er. Men hvis du kigger på din fine SerialPort classe, så er der både et synkront interface, et asynkront interface, et event drevent interface og et async/await interface (det kom dog sikkert efter du skrev din kode). Du valgte det event baserede som er det langsomste.

Hvad i alverden snakker du om? Der er da kun én mulighed, hvis man vil benytte en UART og .Net's indbyggede klasse til netop at supportere en sådan.

Her er en beskrivelse af SerialPort Class i .Net 5.0: https://docs.microsoft.com/en-us/dotnet/api/system.io.ports.serialport?view=dotnet-plat-ext-5.0 , og den er tilsyneladende fuldstændig som version 2.0, som jeg benyttede og har baseret min viden og tutorial på, incl. de 3 events DataReceived, ErrorReceived og PinChanged, som jeg omtalte ovenfor. Der er ikke spor at det synkrone interface, som du nævner, så hvor får du det fra?

.Net er ikke event styret.

Så forklar mig lige hvad de 3 events DataReceived, ErrorReceived og PinChanged så bruges til!

Nej, hele ideen med ThreadPoolen er at kode der kører der.

Dit vrøvl bliver altså ikke mere rigtigt af, at du gentager det. Der er da ingen kode, der kører på TreadPoolen. Den er et sted, hvorfra man kan hente "ready-made" tråde.

Her er et eksempel på, at metoden TreadProc eksekveres på en tråd, der hentes fra tread poolen ved hjælp af metoden QueueUserWorkItem() - præcis som jeg har beskrevet ovenfor og i min tutorial: https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool?view=net-5.0 . Igen er det fuldstændig som under .Net 2.0.

Desværre er det ikke alle funktioner i Win32 API’et der supporterer IOCP og derfor laver man så i .Net løsninger som den med threadpoolen. Det gør man for at få et rent API. Du er så faldet ned i et af hullerne hvor det rene API gav nogle minusser i performance. Hvis du havde brugt .Net mere ville du vide den slags.

Jeg er da fuldstændig klar over, at man bare kan skrive sine egne drivere og kommunikere direkte med IC-kredsen, eller lave et reflection hack, så man får fat i "handle" til den åbnede port og så gøre det den vej, som jeg var tvunget til for at sætte min MaxLinear UART i wide-mode; men hvis man vil lave ordentlige .Net programmer, er det .Net hele vejen og ikke specialdesignede løsninger og mystiske krumspring. Min tag i MSDN er:

Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.

Men hvorfor valgte du så Windows?

Fordi jeg var og er tvunget til det. Jeg ønskede at lave et debug interface til min feltbus Max-i, som kunne køre på en Windows PC og helst under .Net, så andre har let ved at benytte det og evt. lave ændringer, som det f.eks. også blev tilfældet med Texas Instruments. Kombinationen Windows, seriel-USB-seriel og Microsofts elendige SerialPort implementering er dog en løsning, som under ingen omstændigheder er god nok til professionelt brug. Hertil skal bruges en embedded løsning med et RTOS; men til ukritiske debugformål går det.

<em>Det rene nonsense! Tasks bliver da ikke scheduleret i TreadPoolen. Hvor i alverden har du det sludder fra? Formålet med Tread poolen er at undgå at skulle generere en ny tråd hver eneste gang, det er nødvendigt til at behandle en event, som f.eks. DataReceived, ErrorReceived og PinChanged.</em></p>
<p>Jo. . . .</p>
<p>. . .</p>
<p><em>Derfor! Når en event er færdigbehandlet, returneres tråden til poolen igen, så en ny event kan bruge den, uden at .Net skal spilde ca. 300.000 cycles på først at destruere en tråd og så bygge en ny. Det er slemt nok at det sker for mange objekter.</em></p>
<p>Ja det er rigtigt.

Nå, nu begynder du måske at indrømme, at du fik skrevet noget forfærdelig sludder om thread poolen i dit sidste indlæg.

Men her skal jeg huske at gøre opmærksom på at det er den slags tasks der findes i System.Threading.Tasks.

Ja, hvad ellers? System.Threading har da hele tiden været grundlaget for SerialPort klassen og er det stadig, som 5.0 eksemplet ovenfor også klart viser:

using System.Threading;

53
29. juli 2021 kl. 11:30

<em>Der er heller ikke nogen .Net preemptive multitasking. Der er kun Windows preemptive multitasking.</em>
Ja, selvfølgelig, hvor har jeg hævdet andet?

Nu bliver det sgu helt Trump lignende. Lige ovenover skrev du:

… men går via .Net's preemptive multitasking, som kræver mindst ét task switch.

Hvilket meget godt viser at dine argumenter er helt udenfor skiven og ændrer sig fra indlæg til indlæg. Din centrale præmis var at man ikke kunne få .Net IO til at køre hurtigt. Det kan man. Man kan uden problemer fylde et 10G netværk op med data. Man kan også læse data ind og ud fra diske lige så hurtigt som diskene kan levere. Nu har du så gravet dig ned i en enkelt .Net classe og udnævnt den til hele .Net og udtaler dig derefter som mester i det hele uden at have forstået sammenhængen.

så der er tydeligvis noget, du ikke forstår, og det er formodentlig .Net's eventdrevne natur!

.Net er er ikke event drevet. Der er nogle classer der er har event API’er. Men hvis du kigger på din fine SerialPort classe, så er der både et synkront interface, et asynkront interface, et event drevent interface og et async/await interface (det kom dog sikkert efter du skrev din kode). Du valgte det event baserede som er det langsomste.

Ja, dit gæt! Nu begynder du åbenbart at gå efter manden, når du ikke magter at gå efter bolden! Vi havde en god dialog, og det var der også omkring emnet på MSDN, hvor en meget stor del af input til min tutorial stammer fra.

Jeg brugte tid på at overveje om jeg skulle skrive det. Jeg plejer ikke at skrive den slags. Jeg valgte at skrive som jeg gjorde fordi det er rigtigt og fordi det udgør et mønster. Af samme grund stoler jeg ikke på hvad du mener andre måtte have fortalt dig. Det kan du tage som du har lyst.

.Net er netop eventstyret, og derfor kan man ikke nøjes med så få tråde, som der er kerner til. Det er også årsagen til, at I/O ikke eksekveres øjeblikkelig, som mine målinger klart viser, men når det bliver den nye tråds tur til at køre.

.Net er ikke event styret. Der er fx ikke events involveret når du roder med BreakState som i dit eksempel. Der er heller ikke nogen task switching e.lign. involveret. Der er nogle classer der bruger events til nogen ting. Som sagt er event blot smarte funktionspointere. Der er ganske rigtigt nogen steder hvor man har valgt at fyre events af på threadpoolen. Det er ikke nogen specielt performant løsning og ikke noget man bruger når man laver high performance code. Men der er ingen grund til at det skulle tage millisekunder før dit event rent faktisk kører. Hvis der er CPU resourcer til det, så kører koden til dit event med det samme.

Hvilket ville sige 1 på en enkeltkernet processor. I så fald ville .Net umuligt kunne køre, og uden mange tråde, ville du aldrig nogensinde kunne få et realtidssystem som f.eks. proceskontol til at fungere fornuftigt.

Nej, hele ideen med ThreadPoolen er at kode der kører der ikke ”må” vente på noget og at man gør sig færdigt hurtigt. Sådan at den næste kan komme til. Når nogen så alligevel skriver noget skodkode der alligevel blokerer en threadpool thread, så ligger der en mekanisme til at gøre threadpoolen større dynamisk. Det er mega ineffektivt fordi det er noget med nogle timere i sekundstørrelsen (jeg husker ikke detaljerne).

Alas, når IO skal køre rigtigt hurtigt på Windows så skal man bruge IO Completion Ports (IOCP) med tilhørende IO Completion Port threads. De er eksponeret i .Net gennem BeginXXX/EndXXX versioner af diverse funktioner (som fx Read). Desværre er det ikke alle funktioner i Win32 API’et der supporterer IOCP og derfor laver man så i .Net løsninger som den med threadpoolen. Det gør man for at få et rent API. Du er så faldet ned i et af hullerne hvor det rene API gav nogle minusser i performance. Hvis du havde brugt .Net mere ville du vide den slags.

Det er muligt, at business software kan klare sig med "vaskemaskineprogrammering", som det, du åbenbart benytter og foretrækker; men i min verden drejer det sig om effektivitet, så man kan klare sig med en lille processor med begrænset hukommelse, som alt andet lige har langt højere pålidelighed og langt lavere pris end et hårdt pumpet system med adskillige milliarder transistorer alene i CPU'en og en temperaturstigning på måske 40 grader C.

Men hvorfor valgte du så Windows? Du kunne have kodet dine ting på en Arduio e.lign. Der får du netop adgang til metallet. Jeg ved i øvrigt ikke hvad business software er, men når man har software der kører distribueret på mange hundrede eller tusinder af maskiner så bliver performance vigtigt. Men sikkert på en anden måde end når man styrer vaskemaskiner eller andre processer.

Det rene nonsense! Tasks bliver da ikke scheduleret i TreadPoolen. Hvor i alverden har du det sludder fra? Formålet med Tread poolen er at undgå at skulle generere en ny tråd hver eneste gang, det er nødvendigt til at behandle en event, som f.eks. DataReceived, ErrorReceived og PinChanged. Igen et citat fra min tutorial:

Jo. Men her skal jeg huske at gøre opmærksom på at det er den slags tasks der findes i System.Threading.Tasks. Det er et ”nyere” parallelprogrammerings pattern hvor man arbejder med bl.a. continuations i stedet for at vente. Fordi det har vist sig at kode der venter spilder mange CPU cycles.

.Net er i den sammenhæng ikke unik. Det er noget man ser på rigtigt mange platforme fordi det giver et bedre abstraktionsniveau end traditionelle threads. Jeg medgiver dog at niche funktioner som seriel kommunikation ikke haft haft prioritet. Fx er der ikke nogen nem måde at lave continuations på den underliggende Win32 WaitCommEvent funktion fordi den ikke supporterer IOCP. Det er dog ganske nemt med læsning fra og skrivning til seriel porten og supporteret i .Net framework. Unix lignende systemer har samme udfordringer.

Derfor! Når en event er færdigbehandlet, returneres tråden til poolen igen, så en ny event kan bruge den, uden at .Net skal spilde ca. 300.000 cycles på først at destruere en tråd og så bygge en ny. Det er slemt nok at det sker for mange objekter.

Ja det er rigtigt.

52
28. juli 2021 kl. 10:11

Kære Carsten, det er rent nonsens hvad du skriver. Jeg kiggede I source koden til BreakState. Når du sætter BreakState så ender du i 2 funktionskald i Win32 funktionerne SetCommBreak hhv. ClearCommBreak.

Muligt; men de funktionskald eksekveres altså ikke øjeblikkelig, hvilket mine oscilloskopmålinger tydelig viser.

Der er heller ikke nogen .Net preemptive multitasking. Der er kun Windows preemptive multitasking.

Ja, selvfølgelig, hvor har jeg hævdet andet?

Well … det må du selv rode med. Jeg gider ikke bugfixe din kode.

Der er ikke noget at bugfixe.

COMPort.Breakstate = True</p>
<p>Sleep(5)</p>
<p>COMPort.Breakstate = False

Burde altid give en puls på 5-6 ms og ville også gøre det i et realtidsoperativsystem; men det gør det beviseligt ikke under .Net's SerialPort Class, så der er tydeligvis noget, du ikke forstår, og det er formodentlig .Net's eventdrevne natur!

Jeg kender ikke den gode Hamilton, men et gæt er at han har fået nok at din påstående og bedrevidende attitude og blot talt dig efter munden.

Ja, dit gæt! Nu begynder du åbenbart at gå efter manden, når du ikke magter at gå efter bolden! Vi havde en god dialog, og det var der også omkring emnet på MSDN, hvor en meget stor del af input til min tutorial stammer fra.

Suk. Threadpoolen hører til en anden programmeringsmodel end det du snakker om her.

Vrøvl. Citat fra min tutorial:

In case of a DataReceived, ErrorReceived or PinChanged event, the background thread [fired up by SerialPort to wait for something by means of the API function WaitComEvent()] calls the API function QueueUserWorkItem(), <strong>which graps a thread from the thread pool for any further processing of that event</strong>.

.Net er netop eventstyret, og derfor kan man ikke nøjes med så få tråde, som der er kerner til. Det er også årsagen til, at I/O ikke eksekveres øjeblikkelig, som mine målinger klart viser, men når det bliver den nye tråds tur til at køre.

I et velskrevet .Net program er der maksimalt P runnable tråde i threadpoolen hvor P er antallet af kerner i maskinen.

Hvilket ville sige 1 på en enkeltkernet processor. I så fald ville .Net umuligt kunne køre, og uden mange tråde, ville du aldrig nogensinde kunne få et realtidssystem som f.eks. proceskontol til at fungere fornuftigt. Det er muligt, at business software kan klare sig med "vaskemaskineprogrammering", som det, du åbenbart benytter og foretrækker; men i min verden drejer det sig om effektivitet, så man kan klare sig med en lille processor med begrænset hukommelse, som alt andet lige har langt højere pålidelighed og langt lavere pris end et hårdt pumpet system med adskillige milliarder transistorer alene i CPU'en og en temperaturstigning på måske 40 grader C.

Hele ideen med ThreadPoolen er at have et sted for Tasks at blive scheduleret.

Det rene nonsense! Tasks bliver da ikke scheduleret i TreadPoolen. Hvor i alverden har du det sludder fra? Formålet med Tread poolen er at undgå at skulle generere en ny tråd hver eneste gang, det er nødvendigt til at behandle en event, som f.eks. DataReceived, ErrorReceived og PinChanged. Igen et citat fra min tutorial:

Threads are a limited resource. They take approximately 200,000 cycles to create and about 100,000 cycles to destroy. By default they reserve 1 megabyte of virtual memory for its stack and use 2,000-8,000 cycles for each context switch.

Derfor! Når en event er færdigbehandlet, returneres tråden til poolen igen, så en ny event kan bruge den, uden at .Net skal spilde ca. 300.000 cycles på først at destruere en tråd og så bygge en ny. Det er slemt nok at det sker for mange objekter.

51
28. juli 2021 kl. 08:05

Rigtigt; men det er .Net med tilhørende objekter og metoder og ikke Windows kernen, vi diskuterer her. Hvis du f.eks. kalder en af SerialPort metoderne BreakState, DtrEnable eller RtsEnable, sættes Break, DTR og RTS ikke øjeblikkelig, men går via .Net's preemptive multitasking, som kræver mindst ét task switch. Det betyder, at hvis man f.eks. vil lave en puls på mindre end ca. 11 ms ved et singleprocessorkerne system og ca. 16 ms ved et multikernesystem og f.eks. skriver:

Kære Carsten, det er rent nonsens hvad du skriver. Jeg kiggede I source koden til BreakState. Når du sætter BreakState så ender du i 2 funktionskald i Win32 funktionerne SetCommBreak hhv. ClearCommBreak. Det er fundstændigt almindelige funktionskald som man lærer det første dag med programmering. SetCommBreak og ClearCommBreak har været der siden kernen hed Windows NT 3.0. Det er et godt eksempel på at .Net i mange tilfælde i praksis blot renamer funktioner og laver et objektorienteret API. Men alt objektet i praksis indeholder er en Win32 handle.

Der er heller ikke nogen .Net preemptive multitasking. Der er kun Windows preemptive multitasking. Når man laver en .Net process så er det en Windows process … scheduleret af Windows task scheduler. Når man laver en .Net thread så er det en Windows thread … scheduleret af Windows task scheduler (dog er der vist nok noget med SQL Server hvor .Net threads er fibers).

.Net kan ikke preempte din kode for der er ingen mekanisme i CLR til den slags. Events i C# er blot en mere fancy funktionspointer.

Vil den ønskede breakpuls på her 5 ms ikke komme ud i omkring 5 % af tilfældene (testet med et oscilloskop), fordi man kan risikere, at de to BreakState instruktioner eksekveres lige efter hinanden og ikke i den ønskede rækkefølge med forsinkelse imellem.

Well … det må du selv rode med. Jeg gider ikke bugfixe din kode.

Nej. .Net's SerialPort class er grundlæggende eventbaseret, hvilket er udførligt beskrevet i min SerialPort tutorial i f.eks. afsnit "SerialPort Class", så det gider jeg ikke gentage her. For at kunne skrive den tutorial har jeg faktisk været i kontakt med Kim Hamilton fra Microsoft, som har skrevet klassen, så jeg ved godt, hvad jeg taler om!

Åbenbart har du ikke kigget på source koden til classen for så ville du vide at det var nonsens du skrev. Jeg kender ikke den gode Hamilton, men et gæt er at han har fået nok at din påstående og bedrevidende attitude og blot talt dig efter munden. Jeg kan se hvordan du her på sitet opfører dig på den måde. I dette tilfælde uden at forstå hvad du skriver om. Jeg har intet imod smartasses der ved hvad de taler om. Det gør du ikke her.

Her er vi igen fuldstændig uenige. Her er, hvad du kan læse i min tutorial omkring det:

Endnu engang viser du at du ikke forstår emnet. Eksempel: En thread eller process kan ikke spilde en timeslot hvis den har noget fornuftigt at lave. Taskswitch kan ske både preemtivt men også når en process kalder ned i kernen. Specielt sker det hvis man kalder en kerne funktion der ender med at vente.

Alt hvad du skriver passer ind i en 8080 verden hvor der ikke var kæmpe caches, kilobytes af state, multiple processorer, instruction reordering, etc. Og hvor programmer var små. I dag sker de fleste synkroniseringer mellem threads vha. SpinLocks o.lign. Memory barriers (LFENCE, SFENCE, MFENCE) er essentielle for at sikre at ting sker i rigtig rækkefølge. Og meget meget andet.

Hvad mener du med det, og hvem mener du er gået på pension? De fleste programmer indeholder da langt flere tråde, end der er kerner. .Net har f.eks. en tread poll på 25 tråde som standard plus Main, så problemet forsvinder ikke på en flerkernet processor.

Suk. Threadpoolen hører til en anden programmeringsmodel end det du snakker om her. Størrelsen varierer efter antallet af kerner i maskinen og er i øvrigt dynamisk. I et velskrevet .Net program er der maksimalt P runnable tråde i threadpoolen hvor P er antallet af kerner i maskinen. I et velskrevet .Net program venter INGEN af trådene i threadpoolen på noget (bortset fra at få en opgave udstukket). Når threadpoolen er større end P så er det for at beskytte mod deadlocks i mindre velskrevne programmer.

Hele ideen med ThreadPoolen er at have et sted for Tasks at blive scheduleret. Men det er netop ikke en preemptiv scheduler. Det er coorperative scheduling. For at undgå at nogen bliver preemptet. Fx kan der være temmelig skidt hvis en tråd bliver preempted midt i en spinlock.

50
27. juli 2021 kl. 23:09

Hvad mener du med det, og hvem mener du er gået på pension? De fleste programmer indeholder da langt flere tråde, end der er kerner. .Net har f.eks. en tread poll på 25 tråde som standard plus Main, så problemet forsvinder ikke på en flerkernet processor.

Du må korrigere mig hvis min opfattelse af det citerede er forkert. I din beskrivelse af ulemper ved preemptive multitasking skriver du:

"there is no guarantee that a subroutine or function has finished the use of some data before another part of the program can change these data"

Og derved forstår jeg at du mener det modsatte må være tilfælde ved cooperative multitasking. At der er en garanti for at data ikke bliver ændret af andre dele af programmet og at den garanti kommer af at du bruger cooperativ multitasking i modsætning til brugen af semaforer eller andre eksplicite mekanismer.

Det var sikkert også rigtigt i Windows 3.1 men jeg forstår at din definition på cooperativ multitasking i 2021 og med .Net er at du laver sleep(0) kald. Og det giver på ingen måde nogen garanti for at en anden tråd ikke alligevel lykkes at få tildelt timeslices, eventuelt på en anden CPU core, og uden en robust mekanisme til at beskytte data imod ændringer har du en katastrofe undervejs.

49
27. juli 2021 kl. 21:47

Skrevet af nogen der gik på pension inden at multicorr CPUer blev dominerende.

Hvad mener du med det, og hvem mener du er gået på pension? De fleste programmer indeholder da langt flere tråde, end der er kerner. .Net har f.eks. en tread poll på 25 tråde som standard plus Main, så problemet forsvinder ikke på en flerkernet processor.

Det er iøvrigt en chokerende farlig måde at programmere på, at lade flere tråde modificere samme data uden nogen form for beskyttelse.

Det er da da heller ingen, der kunne drømme om! VB.Net tillader ikke cross-tread calls bortset fra de 4 såkaldte tread-safe methods - Invoke, BeginInvoke, EndInvoke og CreateGraphics.

47
27. juli 2021 kl. 11:02

Jeg ved ikke hvem der kaldte det ”The Undocumented PC”.

Det var det flere, der gjorde, og det er sågar titlen på en bog: https://dl.acm.org/doi/10.5555/529231 og https://www.amazon.com/Undocumented-PC-Programmers-Guide-Memory/dp/0201479508 . Jeg har selv haft meget glæde af "PC Principper" af Gunnar Frost til at få en del af den information, som var næsten umulig at finde andre steder (det var før internettets tid).

Som tidligere skrevet: .Net (eller nærmere CLR) er et tyndt lag ovenpå Win32. .Net timere er lavet ovenpå Win32.

Rigtigt; men det er .Net med tilhørende objekter og metoder og ikke Windows kernen, vi diskuterer her. Hvis du f.eks. kalder en af SerialPort metoderne BreakState, DtrEnable eller RtsEnable, sættes Break, DTR og RTS ikke øjeblikkelig, men går via .Net's preemptive multitasking, som kræver mindst ét task switch. Det betyder, at hvis man f.eks. vil lave en puls på mindre end ca. 11 ms ved et singleprocessorkerne system og ca. 16 ms ved et multikernesystem og f.eks. skriver:

COMPort.Breakstate = True</p>
<p>Sleep(5)</p>
<p>COMPort.Breakstate = False

Vil den ønskede breakpuls på her 5 ms ikke komme ud i omkring 5 % af tilfældene (testet med et oscilloskop), fordi man kan risikere, at de to BreakState instruktioner eksekveres lige efter hinanden og ikke i den ønskede rækkefølge med forsinkelse imellem. .Net er altså ikke noget realtidsoperativsystem. Selvfølgelig kunne man da i stedet blot bruge unmanaged code og så snakke direkte med IC-kredsen; men så er det jo ikke .Net længere. Jeg betvivler på ingen måde, at du kan få C, C++, C# og Win32 til at køre med en responstid på under 1 ms; men det kan du ikke garantere, hvis du benytter .Nets indbyggede metoder!

Hvis man laver high performance software bør man undgå taskswitch og det er muligt.

Her er jeg grundlæggende uenig. Uden taskswitching bliver det en forfærdelig gang "vaskemaskineprogrammering"; men problemet er, at Windows task switching kan være så langsom, at det måske kan være nødvendigt at undlade det. Ordentlige computersystemer, som f.eks. RC3500 fra daværende Regnecentralen og visse MIPS CPU'er, kan lave task switching og interrupts på få mikro- eller endog nanosekunder ved blot at selektere en ny registerbank (RC3500 havde vist nok 128).

men seriel kommunikation er heller ikke high performance computing. Det er noget vi har lavet de sidste 25 år på Win32 uden problemer.

Rigtigt, men jeg er én af de meget få, der også har fået det til at køre nogenlunde op til 4 Mbit/s under .Net - dog med en speciel MaxLinear/Exar UART, der kan sender to bytes - data og status - for hver byte, der modtages, da Microsoft's elendige SerialPort implementering ikke bevarer synkroniseringen - gud bedre det. Igen, igen - du kan gøre alt med C, C++ og C# m.fl.; men hvis du vil benytte managed .Net kode, kommer du i hastighedsmæssige problemer, som kræver helt specielle løsninger, hvilket min kontakt til Texas Instruments er et godt eksempel på.

I kernen kører serial kommunikation med interrupts.

Nej. .Net's SerialPort class er grundlæggende eventbaseret, hvilket er udførligt beskrevet i min SerialPort tutorial i f.eks. afsnit "SerialPort Class", så det gider jeg ikke gentage her. For at kunne skrive den tutorial har jeg faktisk været i kontakt med Kim Hamilton fra Microsoft, som har skrevet klassen, så jeg ved godt, hvad jeg taler om!

Der er meget sjældent gode grunde til at kalde sleep med 0, med mindre man har et system der kører med 100% CPU load og en timeslice er for lang. Det lyder som om der er noget helt galt i dit design.

Her er vi igen fuldstændig uenige. Her er, hvad du kan læse i min tutorial omkring det:

The advantage of timeslicing [preemptive multitasking] is that the processes don't have to actively participate in this process and that it is not possible for one process to block the operation of other processes. The disadvantage is a fairly low efficiency compared to cooperative multitasking/multithreading where the programmer selects the ideal switching points [by means of Sleep(0) in .Net]. For example, a timeslice system may waist a lot of time on threads, which cannot utilize the full timeslot, but even worse - there is no guarantee that a subroutine or function has finished the use of some data before another part of the program can change these data. Therefore, a subroutine or function cannot just be called with a reference to the data (ByRef), but must be called with its own copy of the data (ByVal). All this data copying takes a lot of time and increases the necessary stack size. It may even lead to a serious fragmentation of the memory if the data cannot be located on the stack. Therefore, preemptive multitasking is usually used in the PC world where there is a lot of memory and a very fast CPU and where programs from many different vendors must work together, and cooperative multitasking is used in the embedded world where speed and efficiency is a primary concern.

46
27. juli 2021 kl. 09:14

Eller dedikere en CPU core til opgaven.

Du har ret. Fagre nye verden. Selvfølgeligt. Men det har jeg endnu ikke rodet med.

Nej. IBM-PC'en har fået betegnelsen "The Undocumented PC", netop fordi der ikke eksisterede nogen standarder. Derfor var IBM's egen PC også referencen, alle programmer blev testet mod, fordi man ikke kunne regne med, at konkurrerende produkter var 100 % kompatible.

Et sted på loftet har jeg IBM 5150 Hardware Technical Reference Manual. Der er dokumentation af samtlige chips på motherboardet. Der er også en listning af BIOS sådan. Der var ingen custom designede chips i IBMs oprindelige computer. Derfor kunne alle der havde lyst bygge en compatibel computer. Ingen kunne bygge en Amiga (e.lign.) fordi motherboarded var fyldt med custom designede chips som man skulle reverse engineeres. Jeg ved ikke hvem der kaldte det ”The Undocumented PC”. Jeg havde en IBM PC 2nd gen … den med 64Kb RAM på motherboardet men ellers helt som 1st gen. Jeg har aldrig hørt nogen sige den slags.

Jo, det kan det sagtens komme op på, hvis man blot baserer sig på .Net's timerbaserede, preemptive multitasking; men det afhænger af mange faktorer, som beskrevet i min tutorial, og output involverer ofte mindst ét task switch og kan derfor let tage langt over 10 - 15 ms, hvilket jeg også har konstateret med et oscilloskop. Flere efterfølgende outputs på den samme udgang kan også blive lagt samme, så f.eks. en puls forsvinder.

Som tidligere skrevet: .Net (eller nærmere CLR) er et tyndt lag ovenpå Win32. .Net timere er lavet ovenpå Win32. Windows kan lave taskswitch hver eneste gang du kalder ind i kernen. Det er kun når en task ikke kalder ind i kernen at preemptive taskswitching kommer ind i billedet (og dermed længden af et timeslice). Det er ikke anderledes end de fleste andre operativsystemer.

Når man kalder ind i kernen vil Windows gemme nogle få registre. Når Windows laver taskswitch så skal state gemmes. På de nyeste CPU’er kan det være ganske meget fordi de har fået 512-bit vector registre og 32 af dem fylder selvsagt en del. Heldigvis er der lange cache-lines og en store writebuffer. Det er værre når state skal restores. Her skal samme loades og der hjælper ovenstående mindre.

Men det dyre ved taskswitch er invalidering af caches (inkl. HW memory management caches). Og det blev endnu dyrere med Intels og AMDs spectre/meltdown fadæse. Alas, alt det her er givet af at CPU’er bliver stadig mere komplekse fordi alle de nemme ting er gjort. Og vi er meget langt fra dine 10/15ms. Du kan sætte dig ned og tænke over hvordan det er mulig at fylde et 10G netværk med kommunikation hvis det ikke var muligt at håndtere seriel kommunikation (og ja, jeg ved godt at ethernet NICs er mere smarte end UARTS).

Hvis man laver high performance software bør man undgå taskswitch og det er muligt. Man bør også undgå at kalde ind i kernen fordi det koster ca. 5000 cycles (ballpark tal; 10 år siden jeg målte den slags). Det sidste er selvfølgeligt ikke mulig når der er I/O involveret, men seriel kommunikation er heller ikke high performance computing. Det er noget vi har lavet de sidste 25 år på Win32 uden problemer.

Hvis man derimod laver preemptive taskswitching om til cooperative taskswitching ved f.eks. at benytte Sleep(0) til at frigive en task (det trick bruger jeg ofte), kan man selvfølgelig få programmet til at køre langt hurtigere - specielt hvis alle input hentes ind via interrupt; men man kan stadig ikke kommunikere direkte med output som f.eks. modemsignalerne på en RS-232 port, med mindre man bruger unmagaged code, og så er det jo reelt set ikke .Net længere. Alt kan omgås, og det er somme tider eneste mulighed. Jeg har f.eks. måttet lave et reflection hack for at få en handle til den anvendte SerialPort, så IC-kredsen kan sættes op til funktioner, som Windows drivere ikke understøtter; men særlig kønt er det ikke.

Jeg er ikke helt sikker på hvad du mener med interrupt. I kernen kører serial kommunikation med interrupts. Hvad du gør er selvfølgeligt en anden sag. Men du har ikke adgang til kernens interrupt handlere fra user space. Det ville også være farligt. Jeg kiggede lige på dokumentationen og det ser fint ud til at der er adgang til modem signalerne fra .Net code. Jeg gætter dog på at der kan være en smule sequencing der kan give problemer.

Med hensyn til din preemptive taskswitching vs. coorporative taskswitching, så lyder det som om du er på afveje. Der er meget sjældent gode grunde til at kalde sleep med 0, med mindre man har et system der kører med 100% CPU load og en timeslice er for lang. Det lyder som om der er noget helt galt i dit design. Når man laver multithreadede programmer i moderne operativsystemer så bør programmet enten være i gang med noget fornuftigt (fx at lave en beregning) eller vente på noget. Alt andet er spild af CPU cycles.

Ja, man kan lave alt i C/C++ og C#; men hastighedsbegrænsningen i .Net er preemptive multitasking, hvis data skal via flere tasks, hvilket ofte er tilfældet, hvis man benytter de indbyggede I/O metoder. Det kan dog omgås til en vis grad, som beskrevet ovenfor.

Nej, det gør meget lille forskel om det er C/C++ eller C#. Bortset fra garbage collection så er der meget lille forskel på de to verdener rent runtime mæssigt. .Net (CLR) taskswitching er Windows taskswitching. .Net threads er Windows threads. .Net IO er stort set Windows IO.

45
26. juli 2021 kl. 12:00

IBM vandt fordi de startede med at lave en 100% åben platform. Fordi de fra starten inviterede andre ind til at lave kompatibelt hardware og software.

Nej. IBM-PC'en har fået betegnelsen "The Undocumented PC", netop fordi der ikke eksisterede nogen standarder. Derfor var IBM's egen PC også referencen, alle programmer blev testet mod, fordi man ikke kunne regne med, at konkurrerende produkter var 100 % kompatible.

Resten er historie og ikke værd at græde over.

Så spørg Mærsk og andre, der er blevet lagt ned på grund af dette usikre makværk uden hardwaremæssig skrivebeskyttelse, som IBM og Microsoft tilsammen har kreeret!

Taskswitching tager heller ikke 10/15 ms.

Jo, det kan det sagtens komme op på, hvis man blot baserer sig på .Net's timerbaserede, preemptive multitasking; men det afhænger af mange faktorer, som beskrevet i min tutorial, og output involverer ofte mindst ét task switch og kan derfor let tage langt over 10 - 15 ms, hvilket jeg også har konstateret med et oscilloskop. Flere efterfølgende outputs på den samme udgang kan også blive lagt samme, så f.eks. en puls forsvinder.

Hvis man derimod laver preemptive taskswitching om til cooperative taskswitching ved f.eks. at benytte Sleep(0) til at frigive en task (det trick bruger jeg ofte), kan man selvfølgelig få programmet til at køre langt hurtigere - specielt hvis alle input hentes ind via interrupt; men man kan stadig ikke kommunikere direkte med output som f.eks. modemsignalerne på en RS-232 port, med mindre man bruger unmagaged code, og så er det jo reelt set ikke .Net længere. Alt kan omgås, og det er somme tider eneste mulighed. Jeg har f.eks. måttet lave et reflection hack for at få en handle til den anvendte SerialPort, så IC-kredsen kan sættes op til funktioner, som Windows drivere ikke understøtter; men særlig kønt er det ikke.

Nogle skrevet i C/C++ nogle i C#.

Ja, man kan lave alt i C/C++ og C#; men hastighedsbegrænsningen i .Net er preemptive multitasking, hvis data skal via flere tasks, hvilket ofte er tilfældet, hvis man benytter de indbyggede I/O metoder. Det kan dog omgås til en vis grad, som beskrevet ovenfor.

44
26. juli 2021 kl. 10:18

Hvis man vil højere eller køre på ringere hardware (fx 8080) så må man have fat i et realtidsoperativsystem.

Eller dedikere en CPU core til opgaven. Det er blevet en mulighed nu hvor selv embeded mikrokontrollere er multi kerne CPU'er. Lad operativsystem med videre køre på et sæt CPU cores og din tidskritiske løkke på en anden core. Da der ikke kører andet på den core, så er latency så lav som det kan blive. Dit interrupt kan også knyttes til en specifik CPU core.

43
26. juli 2021 kl. 08:29

Krypteringsalgoritmerne i sig selv lader man selvfølgelig hardware om; men der er talrige andre aspekter, som kan optimeres alt efter opgaven. F.eks. vil man på mange procesanlæg kunne u...

Ja man kan lave mange ting. Og de fleste gange når folk begynder med kryptering selv så vil folk der ikke laver andet end kryptering kunne finde huller i deres implementation. Jeg har rodet med kryptering siden begyndelsen af 90'erne (i øvrigt bl.a. af seriel kommunikation). Det er intet problem at skrive en RSA algoritme. Det er heller ikke noget problem at kryptere en 16 byte block. Det svære er at sætte det hele fint sammen sådan at der ikke bliver nogen huller. Eneste sted hvor jeg mener man skal tage fat selv er ved generering af random data. Der har jeg ikke 100% tillid til de data der kommer fra diverse libraries eller kommercielle implementeringer.

Ja, fordi IBM havde de økonomiske muskler til at sætte den igennem som standard - ikke fordi den på nogen måde var bedre - tværtimod.

IBM vandt fordi de startede med at lave en 100% åben platform. Fordi de fra starten inviterede andre ind til at lave kompatibelt hardware og software. Fordi de havde en plan for at rulle skidtet ud på verdensplan til virksomheder. Fordi maskinen ikke blev lanceret som en hjemmecomputer. Alt det ændrede sig senere men det gav PC'en et kæmpe skub fra starten. Og ja ... så gav det også et kæmpe skub at det var IBM. Resten er historie og ikke værd at græde over.

I C og C++ kan man naturligvis lave hvad som helst; men alene interrupt latency er omkring 1 ms i Windows, og jeg nægter at tro, at du kan få managed .Net kode til at køre hurtigere end de ca. 10/15 ms, som taskswitching tager. Windows og .Net er altså ikke noget realtidsoperativsystem.

Selvfølgeligt er interrupt latency ikke 1ms i Windows. Det er ikke engang givet af Windows men af CPU'en du kører på. Der er bunker af ting som genererer interrupts med høj frekvens og hvor en latency på 1ms ville være håbløs. Taskswitching tager heller ikke 10/15 ms. Men det er rigtigt at en timeslice ligger i området 10-20ms. Det er bare noget helt andet.

Det er ganske rigtigt at Windows ikke er et realtidsoperativsystem, men i en situation hvor man har måske 100 mia. instruktioner per sekund at gøre godt med og hvor man flytter ganske lidt information, da kan man fint nå 99.99% sikkerhed for hurtig respons. Hvis man vil højere eller køre på ringere hardware (fx 8080) så må man have fat i et realtidsoperativsystem.

Jeg ved godt jeg ikke får dig til at tro på dette, men hver dag kører der mia. af euros, kroner, dollars, m.fl. gennem systemer jeg har designet og/eller været med til at lave hvor latency krav ligger i 1ms range. Og hvor latency primært kommer fra komplicerede beregninger. Nogle skrevet i C/C++ nogle i C#.

Det ved jeg nok lige så godt som dig! Jeg har faktisk brugt rigtig lang til på at trænge så langt ind i .Net kernen, som jeg har kunnet finde tilstrækkelig information til, for bl.a. at kunne få .Net til at køre hurtigere, end hvad der normalt anses for muligt. Det fremgår også af klart af ikke mindst de indledende afsnit i min SerialPort tutorial!

Du har naturligvis ingen anelse om hvad jeg ved. Jeg kan blot sige at min erfaring med .Net er at når det gælder system funktioner så er det en meget tynd skal ovenpå Win32 og så en garbage collector der kan give store udfordringer når man lave semi realtids programmer. Specielt hvis man har et højt memory footprint (>5GB per process). Så længe man forstår hvad der sker omkring garbage collection og hvilke system funktioner der kaldes, så kan den type .Net kode jeg har rodet med køre med en hastighed på 40-90% af hastigheden af C++ kode.

Det er ganske rigtigt at det ikke er et emne der er meget kommunikation omkring. Dengang jeg rodede med det snakkede jeg med en række folk fra Microsoft og de var interesserede i vores problemer men deres fokus lå på at få ASP.NET til at levere. Der skulle der meget graven og reverse engineering til for at forstå detaljer. Jeg har personligt brugt mange timer på at kigge på genereret assembler kode fra CLR. Det er kode af god kvalitet der kommer ud. Og ved I/O er der sjældent mange instruktioner før der bliver kaldt videre til Win32.

.NET Core ser måske anderledes ud. Det ved jeg ikke; det er efter min tid.

41
25. juli 2021 kl. 15:13

At lave kryptering ordentligt er noget man skal holde sig fra med mindre man forstår det til grunden. Det er ganske enkelt alt for nemt at lave fejl.

Krypteringsalgoritmerne i sig selv lader man selvfølgelig hardware om; men der er talrige andre aspekter, som kan optimeres alt efter opgaven. F.eks. vil man på mange procesanlæg kunne undgå at skulle overføre nøglerne via nettet, hvilket sparer mange problemer, og man kan med fordel benytte tolags kryptering, hvor der er en dødtid efter et afvist forsøg på indtrængning i det andet lag.

Nej, Amiga OS havde ikke 3D. Det var lavet i software ovenpå.

Ja, ligesom raytracking naturligvis også var lavet i software; men man kommer ikke uden om, at på det tidspunkt, hvor Amigaen trods alt kunne dette og bl.a. havde en efter datidens normer ganske fin flysimulator, var IBM stadig på tekstbaseret DOS-niveau.

IBM vandt med et produkt der skabte et gigantisk økosystem af kompatible computere og kompatible udvidelsesmoduler. Amiga blev en parantes i historien.

Ja, fordi IBM havde de økonomiske muskler til at sætte den igennem som standard - ikke fordi den på nogen måde var bedre - tværtimod. Desuden begik Commodore "selvmord" ved udelukkende at fremhæve Amiga som verdens vildeste spillemaskine. Dermed blev det en kamp mod billige spillemaskiner fra bl.a. Nintendo, Sega og Sony, som de ikke i det lange løb kunne vinde, og man blev anset for en useriøs nørd, hvis man brugte Amiga, på trods af, at den også blev brugt af NASA til bl.a. rumfærgeprogrammet: https://www.youtube.com/watch?v=qAPD9HA8Unw , hvilket aldrig blev nævnt i salgmaterialet. IBM-PC'en blev derimod anset for en seriøs forretningsmaskine, så de fleste firmaer valgte den.

Jo det kan man godt [1 ms responstid]. Jeg har lavet den slags i både C/C++ og i .Net.

I C og C++ kan man naturligvis lave hvad som helst; men alene interrupt latency er omkring 1 ms i Windows, og jeg nægter at tro, at du kan få managed .Net kode til at køre hurtigere end de ca. 10/15 ms, som taskswitching tager. Windows og .Net er altså ikke noget realtidsoperativsystem.

Men der kræves at man forstår hvordan .Net fungere (og mere specifikt garbage collection) og at man forstår hvordan moderne operativsystemer virker.

Det ved jeg nok lige så godt som dig! Jeg har faktisk brugt rigtig lang til på at trænge så langt ind i .Net kernen, som jeg har kunnet finde tilstrækkelig information til, for bl.a. at kunne få .Net til at køre hurtigere, end hvad der normalt anses for muligt. Det fremgår også af klart af ikke mindst de indledende afsnit i min SerialPort tutorial!

39
23. juli 2021 kl. 21:44

Amiga's bit-blitter chip var forløberen for vore dages grafikkort, som bit blitting stadig er en stor del af.

Det er måske et meget godt eksempel på at det vi har i dag måske ligner men faktisk er lysår fra datidens teknologi. Den font du læser mit indlæg med er ikke bit blittet og Amigaen kan ikke eftergøre det med nogen hjælp fra hardwaren. Det er nemlig anti-aliaset og bruger alpha værdier til at blente kanten af bogstaverne med baggrunden og på den måde øges skarpheden væsentligt.

Hvis jeg med to fingre kniber lidt på min touch skærm, så zoomer det hele lidt ud eller ind. Hvis jeg trykker og holder alt-tab, så får jeg miniature skærmbilleder af mine kørende programmer, der tilmed opdaterer. Det er ikke bit blit teknologi men 3D rendering.

Det centrale i moderne grafikkort er GPU'en, der med op til flere tusinde kerner kan lave massive parallel matrice beregninger. Amigaen havde ikke noget tilsvarende. Amiga 500 havde end ikke en floating point co processor.

En Amiga 500 havde end ikke hukommelse til at gemme et screenshot af det, der er på din monitor lige nu. Faktisk fylder en enkelt 4k videoframe 63 gange så meget som der var ram i en Amiga 500. Der er en grund til at ting fylder mere nu. Det er fordi vi ikke længere er begrænset og kan lade ting fyldet det, som der er behov for.

38
23. juli 2021 kl. 20:56

Standardmetoder fører ikke altid til det optimale resultat.

At lave kryptering ordentligt er noget man skal holde sig fra med mindre man forstår det til grunden. Det er ganske enkelt alt for nemt at lave fejl. "Selv" for en hardwaremand.

Ja, hele molevitten incl. 3D grafik med ray tracking - og det på et tidspunkt, hvor IBM var på DOS niveau! Amiga's bit-blitter chip var forløberen for vore dages grafikkort, som bit blitting stadig er en stor del af. Desuden havde Amiga fuld multitasking, som var bedre end Windows kan tilbyde idag, og computerarkitekturen (Motorola 68000) var ikke hjernedød, som Intels xx86 system med bl.a. paget addressering og mangel på relativ adressering, så alle hopadresser skal ændres med en relokeringstabel, inden et program kan eksekveres.

Nej, Amiga OS havde ikke 3D. Det var lavet i software ovenpå. Man kunne på det tidspunkt også købe 3D grafik til DOS men Amiga var ganske rigtigt på forkant med udviklingen da de lavede custom chipsettet til Amiga som kunne lave simple geometriske 2D figurer samt flytte rundt på rektangler samt sprites. Men ingen hjælp til 3D grafik.

Resten ... tjaa ... der var fordele og ulemper ved alt. Amiga kom på markedet 4 år efter IBM PC. IBM vandt med et produkt der skabte et gigantisk økosystem af kompatible computere og kompatible udvidelsesmoduler. Amiga blev en parantes i historien.

Du kan ialtfald ikke få I/O fra Microsoft .Net til at køre med en bedre opløsning end 10 ms for singleprocessorsystemer og 15 ms ved multikernesystemer svarende til taskswitchinghastigheden, og så skal du endda stramme balderne og holde dig fra visse routiner, som bruger flere task skift.

Jo det kan man godt. Jeg har lavet den slags i både C/C++ og i .Net. Men der kræves at man forstår hvordan .Net fungere (og mere specifikt garbage collection) og at man forstår hvordan moderne operativsystemer virker. I den forbindelse er længden af en timeslice på Windows (10-20ms alt efter version) ligegyldig. Du har lavet en fejl i dit design hvis det har betydning.

Men design er highperformance systemer på Windows er vist ikke det tråden handlede om. Over and out.

37
23. juli 2021 kl. 16:20

Aha ... nu bevæger du dig ind i kryptologi. Fint, men find nogle standardbiblioteker og metoder. Det er alt for nemt at lave fejl når man roder med det selv.

Standardmetoder fører ikke altid til det optimale resultat. F.eks. er det CRC fejldetekteringssystem, der findes på Max-i, opfundet af mig og udviklet i samarbejde med DTU, og det indebærer bl.a., at man sparer 2 bytes til at angive telegramlængden og samtidig kan udnytte CRC check til at indeholde kendt information som f.eks. datatype, fixed point eksponent og evt. telegramløbenummer, så der ikke skal bruges yderligere bytes til det. Jeg ved altså godt, hvad jeg laver, så du behøver ikke at belære mig.

Hvis det er vigtigt for dig så lav den selv. Du kan boote fra en DVD hvis du vil. Men det er ikke specielt interessant fordi folk hele tiden henter ny kode til deres computere. Det sker i form af JavaScript der downloades fra internettet og kører i folks browsere. Og når folk bliver bedt om hvorvidt de vil installere en opdatering så trykker de altid ja ... fordi almindelige mennesker ingen mulighed har for at forstå hvad en computer rent faktisk laver.

Og præcis derfor er Mærsk og mange andre blevet lagt ned af ransomware!

Hele bootsektoren og operativsystemet incl. dets filer ændres kun ved opdateringer, så en simpel nøgleafbryder kunne forhindre uønskede ændringer her, og hvis al data access (BIOS) blev styret af en sikkerhedscomputer eller chip, var det fuldstændig umuligt for selv den bedste hacker og mest ondsindede hjemmeside at installere noget som helst uden brugeren samtykke. Hele internettet er bygget op på, at man skal kunne klikke sig frem til ny information, så begrebet "ulovlige" klik eksisterer kun som en dårlig undskyldning blandt de programmører, som ikke har formået at lave et sikkert system og nu hævder, at gamle fru Olsen, som har fået inficeret sit system, da burde vide, at hun ikke burde klikke på den link.

Jeg har ingen anelse om hvor dit tal kommer fra.

Det er antallet af sikkerhedsopdateringer.

Who cares? Vare der nogen 3D grafik deri? Hvad med video decoding?

Ja, hele molevitten incl. 3D grafik med ray tracking - og det på et tidspunkt, hvor IBM var på DOS niveau! Amiga's bit-blitter chip var forløberen for vore dages grafikkort, som bit blitting stadig er en stor del af. Desuden havde Amiga fuld multitasking, som var bedre end Windows kan tilbyde idag, og computerarkitekturen (Motorola 68000) var ikke hjernedød, som Intels xx86 system med bl.a. paget addressering og mangel på relativ adressering, så alle hopadresser skal ændres med en relokeringstabel, inden et program kan eksekveres.

Ja ting er blevet mere kompliceret fordi vores systemer er blevet mere komplicerede.

Og fordi softwarenørderne er kommet til. Jeg kan nævne talrige eksempler på sindsygt og unødigt komplicerede standarder incl. OPC-UA (14 bind med tilsammen 1250 sider), CANOpen og USB-PD (USB-C).

Jeg kan naturligvis simulere hele toget.

Også lokomotivførerens kommunikation og alle styrekommandoer, uden at det opdages? Det er det rene sludder og vrøvl, at du vil kunne simulere al kommunikation til et helt tog, når du ikke kender de krypterede kommandoer, togstyresystemet sender, og toget iøvrigt bevæger sig, så du vil skulle spoofe adskillige accesspoints.

Lidt mere avanceret kunne jeg have en modtager på toget der modtager alt hvad toget sender og retransmitterer samme ... blot med nogle få telegrammer udskiftet.

Det er jo lige netop det, du ikke kan, for hvis du kun vil skifte enkelte telegrammer ud, må du først lytte på, hvad der sendes, og du kan ikke fjerne og erstatte med tilbagevirkende kraft! Ærlig talt. Det er noget teoretisk flip, du fyrer af, og intet forhindret, at man også krypterer sine positionstelegrammer, hvis en analyse viser, at det er nødvendigt. Derimod kan du ikke ændre på WiFi egenskaber på godt og ondt, og ingen her er vel i tvivl om, hvor nemt det er at jamme WiFi, så togdriften stopper.

Men i øvrigt kan jeg nævne at jeg har bygget Windows systemer hvor svartidskravet lå på 1ms og hvor omkostningerne ved ikke at overholde samme krav var meget høje.

Du kan ialtfald ikke få I/O fra Microsoft .Net til at køre med en bedre opløsning end 10 ms for singleprocessorsystemer og 15 ms ved multikernesystemer svarende til taskswitchinghastigheden, og så skal du endda stramme balderne og holde dig fra visse routiner, som bruger flere task skift. Prøver du at sende kortere pulser, kommer de ofte slet ikke ud. Det ved jeg med sikkerhed, for jeg har haft et oscilloskop på i forbindelse med brug af den serielle port til høje hastigheder. Jeg har faktisk været ganske langt nede under "motorhjelmen" på .Net og har bl.a. skrevet en tutorial om brug af SerialPort og underliggende systemer: https://www.innovatic.dk/knowledg/SerialCOM/SerialCOM.htm . Det resulterede i, at jeg en dag blev ringet op fra Texas Instruments, som spurgte om tilladelse til at bruge min software og eksempler, for de havde en kunde, der havde prøver alt, hvad han kunne finde på nettet, uden at kunne få det til at virke ordentligt; men med min software kørte det perfekt - bl.a. fordi jeg ved, hvad man ikke skal gøre, hvis man vil have .Net til at flytte fusserne!

36
23. juli 2021 kl. 14:36

Nej. Det forudsætter at telegrammerne altid er de samme, og det vil de f.eks. ikke være i et krypteret sikkerhedssystem, hvor der selvfølgelig indføres "salt".

Aha ... nu bevæger du dig ind i kryptologi. Fint, men find nogle standardbiblioteker og metoder. Det er alt for nemt at lave fejl når man roder med det selv.

Vis mig bare én eneste normal Windows PC, hvor udvalgte partitioner på diverse harddiske kan skrivebeskyttelse ved hjælp af hardware - f.eks. styret af en nøgleafbryder, og hvor Windows stadig er fuldt funktionsdygtig i skrivebeskyttet tilstand bortset fra, at brugerfiler selvfølgelig ikke kan gemmes på en skrivebeskyttet partition.

Hvis det er vigtigt for dig så lav den selv. Du kan boote fra en DVD hvis du vil. Men det er ikke specielt interessant fordi folk hele tiden henter ny kode til deres computere. Det sker i form af JavaScript der downloades fra internettet og kører i folks browsere. Og når folk bliver bedt om hvorvidt de vil installere en opdatering så trykker de altid ja ... fordi almindelige mennesker ingen mulighed har for at forstå hvad en computer rent faktisk laver.

Nej. Op mod 1000 sikkerhedskritiske fejl opstår altså kun, hvis man har mistet overblikket over, hvad man laver,

Jeg har ingen anelse om hvor dit tal kommer fra. Men hvis vi antager at antallet af fejl per linje kode er konstant, så vil et tilstrækkeligt stort system nå 1000 fejl. Det er rent faktisk logik for burhøns.

Alt laves sindsygt kompliceret, og ikke mange standarder er under 1000 sider.

Og jeg kan huske databladet for en Z80 fyldte under 100 sider hvor man kunne se hvor hurtigt samtlige instruktioner kørte. En moderne Intel eller AMD processor har mindst 100 gange så meget dokumentation og ingen kan sige hvor hurtigt en MUL instruktion tager fordi det er kompliceret og afhænger af meget andet.

Ja ting er blevet mere kompliceret fordi vores systemer er blevet mere komplicerede. Den første wifi standard var uhyggelig simpel - nu er det noget som ganske få kan implementere fordi vi kæmper for at hive så meget performance ud af frekvenserne som muligt. Sådan er det på rigtigt mange punkter.

Hele det grafiske system på en Amiga 2000 lå på én 880 kbyte diskette.

Who cares? Vare der nogen 3D grafik deri? Hvad med video decoding? Jeg var med i 90'erne da grafikkort gik fra bare at være dumme til at få funktioner til scrolling, resizing, simple grafik primitiver. Det gjorde både hardware og software mere kompliceret men gav også bedre performance. Den fortsatte udvikling gør at grafik i dag i 4K ikke er specielt dyrt for CPU'en. Hvis man har kørt Windows (eller Linux) med en standard VGA driver så ved man hvor meget det hele har rykket sig.

Kryptering alene gør det ikke, for så kan man netop risikere, at telegrammer med samme indhold hele tiden er ens, så de kan kopieres.

Fint. Det er en almindelig del af kryptering. Der er en fin artikel på wikipedia om Block cipher mode of operation

Hvordan vil du fjerne positionstelegrammer uden at fjerne eller påvirke andre telegrammer til og fra toget? Hvis du blokkerer for alle telegrammer, opdages det øjeblikkelig, og hvis du først vil detektere hvilken type telegram, der er tale om, kan du ikke fjerne det, uden at det kan ses, for starten af telegrammet er jo allerede sendt.

Jeg kan naturligvis simulere hele toget. Fra det øjeblik jeg begynder mit angreb så simulerer jeg hele toget. Jeg sender alt data som toget ellers ville sende. I det simpleste angreb så skal jeg bare have toget til at stoppe i nogle minutter mens resten af verden tror det er kørt videre. Lidt efter kommer næste tog med fuld fart og forventer fri bane ...

Lidt mere avanceret kunne jeg have en modtager på toget der modtager alt hvad toget sender og retransmitterer samme ... blot med nogle få telegrammer udskiftet. En Raspberry Pi med to SDR radioer kunne løse opgaven for få penge. Når vi ser hvad biltyve har lavet med key fob relay angreb så er meget af teknikken sammenlignelig.

omkring 100 ms. Den responstid ser du også idag på hårdt pumpede Windows styringer, så i takt med at hardwareperformance er steget enormt siden da, er softwareeffektiviteten faldet stort set tilsvarende.

Men Windows har ikke til opgave at være et realtidssystem. Men i øvrigt kan jeg nævne at jeg har bygget Windows systemer hvor svartidskravet lå på 1ms og hvor omkostningerne ved ikke at overholde samme krav var meget høje. Det var vel og mærke systemer det lavede komplicerede risikoberegninger hev data fra kryds og tværs. Systemer som det ville have været ganske håbløse at bygge blot 15 år tidligere - både pga. manglende performance og pga. abstraktionsniveauet i sofware var for lavt (og at softwaren derfor blev for kompliceret).

Og med mindre nye argumenter dukker op så bliver det mit sidste indlæg i denne tråd.

35
23. juli 2021 kl. 09:35

Og hardwarefolk laver aldrig fejl. Det er måske derfor at Intel fiksede 11 sikkerhedskritiske fejl i deres CPU'er alene i 2019:

Selvfølgelig laver hardwarefolk også fejl; men netop Intels CPU'er er et skoleeksempel på, hvad der let sker, når systemerne bliver for store til at overskue, og det gør de, fordi mere og mere nødvendigvis må laves i hardware efterhånden som softwarenørderne gør deres systemer mere og mere ineffektive. Derfor indeholder vore dages CPU'er milliarder af komponeneter og bruger tilsvarende mere strøm. En Windows PC er stort set ikke andet end en "object building, object disposing, byte moving machine" med meget lav "payload", som man så må kompensere for i hardware og strømforbrug.

Da jeg startede med at lave elektronisk procesautomatik for omkring 44 år siden hos Søren T. Lyngsø A/S, kunne vi styre ca. 80 enheder (transportører, spjæld, tovejsfordelere etc.) på f.eks. en foderstoffabrik med en 2 MHz, 8080 mikrocomputer med 6 kbyte RAM og 8 kbyte EPROM, og på grund af en meget effektiv hændelsesstyring var responstiden typisk omkring 100 ms. Den responstid ser du også idag på hårdt pumpede Windows styringer, så i takt med at hardwareperformance er steget enormt siden da, er softwareeffektiviteten faldet stort set tilsvarende. Bare 25 % CPU load på en 4-kernet Windows computer sløver brugergrænsefladen ned til sneglefart, fordi Microsoft gemmer WM_PAINT beskeder, indtil der ikke er andet at lave - gud bedre det! Det sidste, man må miste på et proceskontrolsystem, er brugergrænsefladen, så man ikke mister kontrollen over anlægget.

Proceskontrolingeniører, som mig, der risikerer at blive kaldt på service på de mest ubelejligende tidspunkter, hvis det hele ikke virker 100% 365/24/7, og softwarenørder, der er vant til, at man bare kan genstarte og opdatere, uden at det koster en formue, "er bare ikke fra samme planet". Derfor er vi også, som her, vildt uenige om, hvordan radiosystemet til et sikkerhedssystem bør udformes. Softwarenørderne kender WiFi og har valgt det, bl.a. fordi de så kan foretage vedligehold og softwareopdateringer over samme system; men som radioamatør med A-licens ved jeg godt, hvad en høj båndbredde koster i performance, hvis det drejer sig om at sikre data mod forstyrrelser.

34
22. juli 2021 kl. 22:23

Nej, jeg fatter ikke, at vore dages programmører har så lidt overblik over, hvad de selv laver, at de kan lave op mod 1000 sikkerhedskritiske fejl i det samme operativsystem!

Og hardwarefolk laver aldrig fejl. Det er måske derfor at Intel fiksede 11 sikkerhedskritiske fejl i deres CPU'er alene i 2019: https://www.zdnet.com/article/intel-fixed-236-bugs-in-2019-and-only-5-11-bugs-were-cpu-vulnerabilities/

Få softwarefejl har været ligeså dyre som hardwarefejlene Meltdown og Spectre.

Når du siger 1000 sikkerhedskritiske fejl og manglende overblik, så er det fordi du også tæller en masse med der ikke traditionelt er operativsystemet. Det kan godt være at der følger en webbrowser med Windows men browseren er ikke operativsystemet. Ser du kun på en Linux kerne, der er begrænset til det du skal bruge, eksempelvis noget embedded Linux, så er det langt mere overskueligt.

31
22. juli 2021 kl. 19:48

Hvis jeg kan generere positionstelegrammer så kan jeg også simulere et tog.

Nej. Det forudsætter at telegrammerne altid er de samme, og det vil de f.eks. ikke være i et krypteret sikkerhedssystem, hvor der selvfølgelig indføres "salt".

Alas, hvis man vil så kan man køre både Windows og Linux fra readonly medier. Men der ryger brugervenlighed og omkostningerne stiger.

Vis mig bare én eneste normal Windows PC, hvor udvalgte partitioner på diverse harddiske kan skrivebeskyttelse ved hjælp af hardware - f.eks. styret af en nøgleafbryder, og hvor Windows stadig er fuldt funktionsdygtig i skrivebeskyttet tilstand bortset fra, at brugerfiler selvfølgelig ikke kan gemmes på en skrivebeskyttet partition.

Men en af grundene til at der er fejl i software er at det er meget billigere at rette fejl i software end i hardware. Derfor er testningen også mindre.</p>
<p>. . .</p>
<p>Så hele din anke handler grundlæggende om at du mener der skal bruges flere penge på softwaren og det er naturligvis et validt synspunkt.

Nej. Op mod 1000 sikkerhedskritiske fejl opstår altså kun, hvis man har mistet overblikket over, hvad man laver, og uden overblik kan du stoppe lige så mange penge i projektet, du vil, uden at kvaliteten bliver nævneværdig højere. Det, man i stedet skal gøre, er at simplificere til et niveau, hvor det er menneskeligt muligt at overskue, og det er netop hovedproblemet med dagens IT-nørder. Det magter de ikke. Alt laves sindsygt kompliceret, og ikke mange standarder er under 1000 sider. Hele det grafiske system på en Amiga 2000 lå på én 880 kbyte diskette. Til sammenligning fylder Windows adskillige Gbytes uden at kunne ret meget mere. Det er problemet. Det nye kampfly F-35 har over 8 millioner kodelinjer, og netop derfor magter de ikke at få det til at virke. Keep It Simple! Det er nøglen til at lave noget, der virker!

Som sagt er den eneste måde at opnå sikker kommunikation ved at sikre mediet eller vha. kryptering.

Kryptering alene gør det ikke, for så kan man netop risikere, at telegrammer med samme indhold hele tiden er ens, så de kan kopieres. Det er også nødvendigt med noget tilfældig "salt". Alternativt kan man indføre et telegramløbenummer, hvis indholdet ikke er hemmeligt som f.eks. en togposition. Det sikrer, at man ikke kan indsætte eller fjerne telegrammer, uden at det opdages.

Dertil er hverken 7-bit tællere, CRC, CDMA, vandalbeskyttede accesspoints, o.lign. nok.

Jo, det kan det faktisk godt være. Fejlsikkerhed handler ikke om korrekte data, men om at sikre, at en fejl eller et forsøg på jamming eller spoofing opdages med en given sikkerhed, som for SIL 3 er maksimalt én farlig udetekteret fejl pr. 5000 år ved kontinuert drift. Bemærk at fejl godt må forekomme - bare de opdages. Hvis du vil snyde et telegramserienummer, skal du fjerne et telegram og erstatte det af et andet - ellers opdages det; men så er vi tilbage til mit gamle spørgsmål, som du hele tiden undlader at svare på: Hvordan vil du fjerne positionstelegrammer uden at fjerne eller påvirke andre telegrammer til og fra toget? Hvis du blokkerer for alle telegrammer, opdages det øjeblikkelig, og hvis du først vil detektere hvilken type telegram, der er tale om, kan du ikke fjerne det, uden at det kan ses, for starten af telegrammet er jo allerede sendt.

30
22. juli 2021 kl. 10:57

Det kan du heller ikke, for du kan ikke beskrive, hvordan du vil blokkere for togets positionstelegrammer, som du så spoofer; men ikke for alle andre telegrammer til og fra toget, så det ikke bliver opdaget øjeblikkeligt.

Hvis jeg kan generere positionstelegrammer så kan jeg også simulere et tog. Et par ture rundt med S-tog med en laptop og en SDR modtager og så har jeg nok til at simulere et tog. Med mindre der er en form for authentikering på beskederne.

Det kunne man med disketter og tidligere tiders harddiske; men det kan ikke lade sig gøre, hvis operativsystemet hele tiden skal have skiveadgang.

Vi skal tilbage til 50'erne før de første systemer hvor data og program blev gemt på samme fysiske medie så dagen. Det var også normen for Unix. Alas, hvis man vil så kan man køre både Windows og Linux fra readonly medier. Men der ryger brugervenlighed og omkostningerne stiger.

Nej, jeg fatter ikke, at vore dages programmører har så lidt overblik over, hvad de selv laver, at de kan lave op mod 1000 sikkerhedskritiske fejl i det samme operativsystem!

Nu ved jeg ikke hvilket operativsystem det er du tænker på og hvor meget du indregner i "operativ systemet". Men en af grundene til at der er fejl i software er at det er meget billigere at rette fejl i software end i hardware. Derfor er testningen også mindre. Du vil også kunne opleve hardware komponenter hvor hardware fejl fikses i software ... fordi det er billigt. Så hele din anke handler grundlæggende om at du mener der skal bruges flere penge på softwaren og det er naturligvis et validt synspunkt.

Det kan vi have en lang diskussion om og det gider jeg ikke.

Hvis det ikke var for hardware, havde du ganske simpelt ingen kommunikation. Kan du ikke lige fortælle mig, hvordan du f.eks. vil realisere CDMA og bitvis busarbitrering i software? Jeg vil også gerne vide, hvordan du vil opnå SIL 4 i software alene, når det ifølge standarden ikke er muligt.

Selvfølgeligt har vi brug for hardware. Det jeg skrev var at hardwarefolk skulle holde sig fra at definere kommunikationsprotocoller. Som sagt er den eneste måde at opnå sikker kommunikation ved at sikre mediet eller vha. kryptering. Naturligvis kan man implementere kryptering i hardware (ofte implementerer man dele af krypteringen i hardware af hensyn til hastighed) men det bliver dyrt og ufleksibelt hvis det hele laves i hardware.

Du fatter åbenbart heller ikke forskellen mellen fejlsikkerhed og funktionssikkerhed. Fejlsikkerheden er relativ let at sikre; men det, vi diskuterer her, er funktionssikkerhed herunder evnen til at modstå jamming, så man ikke kan stoppe hele S-togs nettet, og det er straks betydelig sværere.

Æh ... min anke var at du mente at et 7-bit sequencenumber var nok til sikkerhed. Eller at hænge et accesspoint højt op i en mast var det samme. Jeg er naturligvis enig i at togstyring forsøges at gøres så resistent mod jamming o.lign. som muligt sådan at driften ikke påvirkes. Men vigtigere er det at sikre at tog ikke kører ind i hinanden og såfremt togene er fuldautomatiske så kræves der at de kan stole på de informationer de udveksler. Dertil er hverken 7-bit tællere, CRC, CDMA, vandalbeskyttede accesspoints, o.lign. nok.

29
21. juli 2021 kl. 20:43

... kan findes her: <a href="https://backend.orbit.dtu.dk/ws/files/1289..">https://backend.orbit.dtu…;
<p>Det er anbefalet læsning hvis man vil diskutere CBTC funktionalitet og sikkerhed. José og Jahanzeb er virkelig grunde i deres "Radio communication for Communications-Based Train Control (CBTC): A tutorial and survey", og tiden er givet godt ud på at læse de 26 sider. Københavns s-tog er selvfølgelig også med (forfatterne er begge PhD'er fra DTU).</p>
<p>I afsnit 7 (VIII) kan man se en mulig forklaringerne på at det er gået galt for S-toget: Manglfund standardisering og mangelfuld håndhævelse af standarder.

Tak for det Torben.

Jeg bemærker at den mindste kanalbredde man kan vælge i standard wifi er 20 MHz. Eftersom at EU kun har tildelt 20 MHz til formålet, så er der kun én kanal til rådighed. Men samtlige systemer beskrevet i ovenstående forudsætter mindst 2 kanaler. Typisk med hver "mast" på alternerende frekvenser.

S-tog har valgt at have meget stor afstand mellem masterne. 600 meter selvom forfatterne anbefaler maksimalt 200 meter. De går fra at have rådighed over 50 Mhz til 20 MHz, hvilket svarer til at de går fra at have 2 uafhængige wifi kanaler til kun én.

Med alle master på samme frekvens må man forvente flere kollisioner og lavere tilgængelig båndbredde. Det med båndbredde burde ikke være et problem, da der skal være rigeligt til rådighed?

De tænker måske at det er nødvendigt at mindske afstanden mellem master for at kompensere. Fordoble eller tredoble antal af master, hvilket næsten er at starte forfra.

Alternativt kunne de se på om det er muligt at hacke baserne til at bruge 5 eller 10 MHz kanaler. Der er et skema i det linkede der antyder at kan være muligt. Det er ikke standard WIFI men det vil ikke være en stor ændring. Jeg undrer mig også over at forfatterne kun beskriver systemer der bruger to eller flere kanaler, hvis det Københavnske S-tog er det eneste system i EU der bruger to kanaler. Hvordan klarer de andre baner det problem?

28
21. juli 2021 kl. 19:37

Carsten du er så langt fra kravspecifikation som man kan komme. FT8 bruger 30 sekunder på at sende 77 bits og det er ikke specielt nemt at lykkes over store afstande med få watt. FT8 er i øvrigt på ingen måde imun overfor interferens.

Det har jeg heller ikke skrevet. Læs dog, hvad jeg skriver:

... FT8 er et godt eksempel på (<strong>benytter dog GFSK og ikke CDMA</strong>).

Jeg brugte bare FT8 som er eksempel på, at når man kun har brug for ganske få bit/s, er det muligt at grave disse frem af støjen, så man kan kommunikere til den anden side af jordkloden med ganske få watt, hvilket ville være helt umuligt ved en højere bit-rate. Med mere sofistikerede teknikker kan man sandsynligvis gøre det endnu bedre end FT8.

WiFi er skabt til at sende meget store datamængder meget hurtigt. Det er fint til softwareopdateringer; men efter min mening er det tåbeligt til brug ved de omkring 50-100 kbit/s, som der er behov for til selve sikkerhedssystemet. Ved så lave hastigheder, er der andre modulationsarter, der har langt bedre egenskaber med hensyn til jamming etc. Det er jo allerede nu næsten standard for indbrudstyve at jamme WiFi, så trådløse kameraer ikke virker.

27
21. juli 2021 kl. 15:59

Nej, det er det ikke, for ved kun omkring 50 bit/s, kan du grave signalet frem, uanset om det er meget lavere end støjen. Det er af samme årsag, at få watt rækker til FT8 kommunikation til den anden side af jordkloden.

Carsten du er så langt fra kravspecifikation som man kan komme. FT8 bruger 30 sekunder på at sende 77 bits og det er ikke specielt nemt at lykkes over store afstande med få watt. FT8 er i øvrigt på ingen måde imun overfor interferens.

26
21. juli 2021 kl. 14:31

Men det er sådan set ligegyldigt. Hvis jeg kan få toget til at stoppe fx. i et sving men få resten af verden til at tro at det kører videre

Det kan du heller ikke, for du kan ikke beskrive, hvordan du vil blokkere for togets positionstelegrammer, som du så spoofer; men ikke for alle andre telegrammer til og fra toget, så det ikke bliver opdaget øjeblikkeligt.

Nu var det faktisk ikke Microsoft der opfandt software gemt på disk. Siden 50'erne har store IT systemer haft software i writable stores. Selv din fine C64 kunne fås med diskettedrev hvor softwaren kunne opdateres

Det har intet med det at gøre. Det handler om, om man hardwaremæssigt kan skrivebeskytte et medie eller dele af et medie, så en hacker ikke kan kryptere det hele. Det kunne man med disketter og tidligere tiders harddiske; men det kan ikke lade sig gøre, hvis operativsystemet hele tiden skal have skiveadgang.

Resten af dit snak om alle mulige fejl der er lavet (surprise: der laves fejl alle steder) viser blot at du ikke forstår hvad du snakker om på det område og at du blander ting sammen som intet har med emnet at gøre.

Nej, jeg fatter ikke, at vore dages programmører har så lidt overblik over, hvad de selv laver, at de kan lave op mod 1000 sikkerhedskritiske fejl i det samme operativsystem!

Endnu engang viser du at hardware folk skal holde sig fra at designe sikker kommunikation.

Hvis det ikke var for hardware, havde du ganske simpelt ingen kommunikation. Kan du ikke lige fortælle mig, hvordan du f.eks. vil realisere CDMA og bitvis busarbitrering i software? Jeg vil også gerne vide, hvordan du vil opnå SIL 4 i software alene, når det ifølge standarden ikke er muligt.

Nej, du. Det er softwarenørderne, der skal holdes ude, hvis man vil have noget, der virker. CANOpen er et skoleeksempel på, at de kan ødelægge selv den bedste hardwareløsning. Her har de kompliceret det hele aldeles unødigt og bl.a. fjernet muligheden for at bruge den lange identifier og dermed muligheden for en fornuftig procesnummerering, ødelagt muligheden for bare at kunne tilkoble en debugger, da der først skal oprettes en kommunikationskanal mellem enheder, før de kan kommunikere, og ødelagt noget af det mest geniale i CAN - nemlig publisher-subscriber modellen - og altsammen uden at opnå én eneste fordel! Se så på Max-i hvor enkelt og effektivt, der kan gøres i ren hardware!

Sikkerheden skal naturligvis være bibeholdt uanset om nogen bryder ind i et accesspoint.

Du fatter åbenbart heller ikke forskellen mellen fejlsikkerhed og funktionssikkerhed. Fejlsikkerheden er relativ let at sikre; men det, vi diskuterer her, er funktionssikkerhed herunder evnen til at modstå jamming, så man ikke kan stoppe hele S-togs nettet, og det er straks betydelig sværere.

25
21. juli 2021 kl. 13:48

Måske, men det afholder ialtfald rødderne fra for sjov at jamme systemet. Desuden mangler du lige at svare på, hvordan du vil sikre, at det kun er positionstelegrammerne fra toget, der blokkere, og ikke alle andre incl. togstyringstelegrammer TIL toget, da jammingen ellers ville blive opdaget meget hurtigt, og toget vil stoppe.

Well ... man kan godt overdøve signalet. Nu er jeg ikke antennemand og skal derfor afholde mig fra at gå ind i den diskussion.

Men det er sådan set ligegyldigt. Hvis jeg kan få toget til at stoppe fx. i et sving men få resten af verden til at tro at det kører videre ... så vil det næste tog tro at der er fri bane. Det essentielle er i denne sammenhæng at den centrale styring skal kunne stole på de positionsangivelser der kommer fra toget og togene skal tro på de positionsangivelser de modtager centralt.

Vrøvl igen. Der har aldrig nogensinde været så store sikkerhedsproblemer med IT, som efter at softwarenørderne kom ind i billedet med deres ekstremt komplicerede og ineffektive standarder, som ikke engang de selv kan overskue, så implementeringen altid vil være fuld af huller ... bl.a. bl.a. bl.a. ....

Nu var det faktisk ikke Microsoft der opfandt software gemt på disk. Siden 50'erne har store IT systemer haft software i writable stores. Selv din fine C64 kunne fås med diskettedrev hvor softwaren kunne opdateres. Når det blev valgt var det naturligvis fordi en af fordelene ved en computer i forhold til (næsten) alle andre maskiner er at den ikke fra fabrikken et bebegrænset til at løse et begrænset antal opgaver. Ejeren af maskinen vælger skal den skal gøre.

Resten af dit snak om alle mulige fejl der er lavet (surprise: der laves fejl alle steder) viser blot at du ikke forstår hvad du snakker om på det område og at du blander ting sammen som intet har med emnet at gøre.

Hvordan skulle det fysisk være muligt? Man sætter vel næppe accesspoints, så de er lette at nå, for så vil man da bare kunne smadre dem med en hammer.

Endnu engang viser du at hardware folk skal holde sig fra at designe sikker kommunikation. Sikkerheden skal naturligvis være bibeholdt uanset om nogen bryder ind i et accesspoint. Det skal den fordi et accesspoint der hænger på en mast ude i naturen naturligvis ikke kan opfattes som sikker.

Din CDMA kode er i øvrigt også at betragte som kryptering.

Ja ... men det er ikke end-to-end kryptering og den foregår i kasser som ejeren ikke har fuld fysisk kontrol over. Dermed er sikkerheden ikke garanteret. Kravet må være at enten kommer der ingen data eller også kan man stole på data. Det er ikke helt klart når man læser den fine DTU rapport om der kun er kryptering af over-the-air signalet eller om det er end-to-end.

24
21. juli 2021 kl. 13:01

Du skal bare hæve støjgulvet til et niveau hvor den påkrævede båndbredde ikke kan opretholdes. Det er faktisk ganske trivielt på et frekvensområde på kun 20 MHz.

Nej, det er det ikke, for ved kun omkring 50 bit/s, kan du grave signalet frem, uanset om det er meget lavere end støjen. Det er af samme årsag, at få watt rækker til FT8 kommunikation til den anden side af jordkloden.

Min gamle matematiklærer (Her)mandsen sagde ofte: "Hvis man vil lede efter en neger, er det rart at vide, at han er sort", og det er det samme, CDMA gør. I sin simpleste form inverterer (XOR'er) man inputsignalet med en lang kendt kode, hvorefter man integrerer. Dermed integreres al støj og anden kommunikation på samme frekvens ud; men det signal, man leder efter, vil hele tiden give det samme bidrag (1 XOR 1, eller 0 XOR 0), så signalet langsomt graves frem af støjen. Det gør det også svært at jamme, for kender du ikke koden, vil dine signaler blot blive midlet ud af integrationen. Jo langsommere, kommunikationen er i forhold til båndbredden, jo bedre virker det; men hele den fordel sættes jo over styr, hvis man vil have båndbredde nok til at sende softwareopdateringer over samme kanal som positionsdata.

22
21. juli 2021 kl. 12:29

... kan findes her: <a href="https://backend.orbit.dtu.dk/ws/files/1289..">https://backend.orbit.dtu…;.

Tak for link, og den afkræfter også, at det kun er frekvensområdet, man benytter, som nogen her har påstået:

The radio system used in the Copenhagen S-train CBTC system, called Airlink [42], is based on Wi-Fi.

Dermed arver systemet også WiFi's egenskaber på godt og ondt! Tilsyneladende er WiFi valgt, fordi systemet bl.a. har båndbredde nok til "maintenance" og softwareopdateringer; men man kan så stille spørgsmålstegn ved det hensigtsmæssige i at blande den slags sammen med sikkerheds- og togstyringssystemet.

Sjovt nok nævner linken også, at mange andre har valgt spread-spectrum, som jeg nok også ville gøre til sikkerhed og togstyring.

21
21. juli 2021 kl. 12:11

... kan findes her: https://backend.orbit.dtu.dk/ws/files/128950142/COMST2661384.pdf

Det er anbefalet læsning hvis man vil diskutere CBTC funktionalitet og sikkerhed. José og Jahanzeb er virkelig grunde i deres "Radio communication for Communications-Based Train Control (CBTC): A tutorial and survey", og tiden er givet godt ud på at læse de 26 sider. Københavns s-tog er selvfølgelig også med (forfatterne er begge PhD'er fra DTU).

I afsnit 7 (VIII) kan man se en mulig forklaringerne på at det er gået galt for S-toget: Manglfund standardisering og mangelfuld håndhævelse af standarder.

20
21. juli 2021 kl. 12:00

Jeg ville sende bredspektret støj.

Hvad skulle det hjælpe? CDMA vil da netop integrere bredbåndet støj ud, og du vil sprede din sendeeffekt over et stort frekvensområde, så den bliver for lille til at overstyre.

Da du har mulighed for at stå helt op ad modtageren

Hvordan skulle det fysisk være muligt? Man sætter vel næppe accesspoints, så de er lette at nå, for så vil man da bare kunne smadre dem med en hammer.

De behøver i øvrigt ikke klatre op på taget. Afstand betyder alt i radiokommunikation og selvom taget er lavet af metal, så er toget ikke et faraday bur.

Nej, men taget virker som jordplan for en 1/4 bølge, 5/8 eller anden stakket antenne. Det er aldeles utænkeligt, at du kan jamme fra indersiden af toget.

Mobiltelefoner virker eksempelvis fint inden i toget.

Ja, for de skal jo ikke sende op til en boks på oversiden af taget.

Det vigtige er at designe et system hvor en sådan forstyrrelse ikke medfører fare.

Ikke i denne sammenhæng. Du må lære at skelne mellem fejlsikkerhed, som er nem at realisere - bare stop toget ved en detekteret fejl, og funktionssikkerhed, dvs. at holde togdriften kørende trods fejl og forsøg på jamming. Sådan er det også ved procesautomatik. Bare at stoppe ved den mindste fejl kan koste tusindvis af kr.

19
21. juli 2021 kl. 11:30

Rigtigt; men CDMA er altså ikke så let at jamme, hvis du ikke kender koden, da signalet ellers bare ligner støj. så hvad vil du sende?

Jeg ville sende bredspektret støj. Der er kun tale om 20 MHz for hele båndet, mindre end hvad moderne wifi fordeler subcarriers ud over. Da du har mulighed for at stå helt op ad modtageren, så er det utænkeligt at togets/basens sender vil kunne sende kraftigt nok til at overdøve dit støj.

De behøver i øvrigt ikke klatre op på taget. Afstand betyder alt i radiokommunikation og selvom taget er lavet af metal, så er toget ikke et faraday bur. Mobiltelefoner virker eksempelvis fint inden i toget. Skulle det være nødvendigt at være udenpå toget, så er det nemt klaret med en lille mobil sender i en kasse sat på toget med en magnet.

Nu synes jeg ikke vi behøver debatere præcis hvordan man kan forstyrre togdriften. Der er også mange andre måder. Det vigtige er at designe et system hvor en sådan forstyrrelse ikke medfører fare. Til det er kryptering så åbenlyst at det vil være mærkeligt ikke at gøre brug af det. Det er lige meget at opfinderen mener det vil være bøvlet at sende et falsk signal, hvorfor overhovedet have det som mulighed? Din CDMA kode er i øvrigt også at betragte som kryptering.

18
21. juli 2021 kl. 10:40

Well ... en terrorrist kunne kravle op på taget mens toget stod stille om natten. Han kunne så aktivere systemet remotely om dagen når toget var i rute.

Måske, men det afholder ialtfald rødderne fra for sjov at jamme systemet. Desuden mangler du lige at svare på, hvordan du vil sikre, at det kun er positionstelegrammerne fra toget, der blokkere, og ikke alle andre incl. togstyringstelegrammer TIL toget, da jammingen ellers ville blive opdaget meget hurtigt, og toget vil stoppe.

Hvis man kan bygge en modtager til skidtet så kan man også bygge en jammer.

Rigtigt; men CDMA er altså ikke så let at jamme, hvis du ikke kender koden, da signalet ellers bare ligner støj. så hvad vil du sende? Benytter du en forkert kode, vil modtageren opfatte din jamming som støj, som vil blive integreret ud. Det ér altså forskel på, hvor følsom de forskellige modulationsmetoder er over for jamming og dermed hvor let, det er at skaffe udstyr, der kan gøre det.

Efter min mening er det ikke ligefrem studenderhuen, der trykker, når man vælger frekvenser til et sikkerhedssystem lige op ad et licensfrit bånd, hvor alverdens kineserskrammel kan komme til at operere, og hvor billig standardudstyr blot skal detunes en anelse for at kunne forstyrre.

Når vi snakker sikkerhed i tog så kan modstanderen godt stå med "militært udstyr".

Ja, men det er ikke så let at skaffe via internettet. Det svarer til forskellen mellem at skaffe en kniv til angreb og så et højteknologisk automatvåben.

Hele din forklaring viser ret godt hvorfor hardware folk skal holde sig langt væk fra at lave kommunikationsprotocoller: De tror at deres hardware er unik og at ingen kan lave det samme. Den slags fejler altid. Den eneste måde at beskytte kommunikation er enten ved at beskytte mediet (fx. kabler der er placeret i et beskyttet miljø eller en betroet kurer) eller med kryptografi.

Vrøvl igen. Der har aldrig nogensinde været så store sikkerhedsproblemer med IT, som efter at softwarenørderne kom ind i billedet med deres ekstremt komplicerede og ineffektive standarder, som ikke engang de selv kan overskue, så implementeringen altid vil være fuld af huller. Der har af den årsag været op mod 1000 sikkerhedsopdateringer alene til Windows 7. Man patcher, når hackerne finder fejlene, men har selv opgivet og overlader nu sikkerheden til 3. part i form af antivirus software. Commodore Amiga var for over 35 år siden stort set virus- og hackerfri af den simple, hardwaremæssige årsag, at alt incl. selvfølgelig ROM-kernel kunne skrivebeskyttes; men efter at Microsoft kom til med bl.a. DLL-helvede og registreringsdatabase, er det ikke længere muligt. Hvis hardwareingeniører, som mig, havde designet dagens computersystemer, var Mærsk ikke blevet lagt ned af ransomware. Problemet er, at softwarenørderne i deres naivitet tror, at de kan beskytte noget som helst med software; men reelt set kan det kun gøres ved at blokkere skrivestroberne i hardware f.eks. styret af en nøgleafbryder. Tør du besøge en vilkårlig hjemmeside med antivirus slået fra? Nej vel; men det kunne man med sindsro med en 35 år gammel Commodore Amiga, hvis den ellers havde haft en browser og en internetforbindelse. Sikkerhed i software - glem det! Ser du på IEC 61508 sikkerhedsstandarden, er kravene til software 10 gange større end til hardware, fordi software er langt mere uforudsigeligt. Det betyder, at SIL 4 (mulig massedød), som et jernbanesystem skal leve op til, ganske simpelt ikke kan realiseres i software alene.

Iøvrigt er det fine ved hardware, at det normalt ikke kan omprogrammeres til anden funktion, end den forventede. Der er derfor heller ingen "mousejack" problemer.

I øvrigt var det dig der blandede GPS ind i historien. Som sagt: GPS kan spoofes og i øvrigt er præcisionen ikke altid høj nok til at sige hvilket af to parallele spor det står på.

Jeg blandede kun GPS ind i det som tidssynkonisering til time division multiplex - ikke som positionsangivelse. Da der ikke er GPS forbindelse i en tunnel, må man naturligvis hare en lokal krystaloscillator eller bedre, som kan overtage synkroniseringen der. Det fine er så, at da man derved har to systemer, kan de konstant overvåge hinanden, så hvis der sker afvigelser ud over det forventede, genereres en fejlmeddelelse. Det system benyttes iøvrigt også på Max-i, som normalt kører på en intern RC-oscillator. Forbindes en ekstern (mere nøjagtig) oscillator, køres på den i stedet; men kun hvis den ikke afviger mere end omkring +/-10 %,.

17
20. juli 2021 kl. 15:17

Hvordan vil du jamme udsendelse af signaler fra toget, hvis det sker fra en antenne på taget, som jo er af metal? Vil du kravle derop under køreledningerne og installere udstyr, og hvordan vil du styre, at alle andre telegrammer end positionsangivelserne ikke også bliver blokkeret, da jammingen ellers hurtigt vil blive opdaget.

Well ... en terrorrist kunne kravle op på taget mens toget stod stille om natten. Han kunne så aktivere systemet remotely om dagen når toget var i rute.

Du kan måske med en retningsantenne jamme accesspoints, så de ikke modtager noget - ikke mindst hvis systemet er WiFi lignende; men målet med at udvikle spread spectrum CDMA til militærbrug var jo netop at udvikle systemer, der er betydelig sværere at jamme. Jeg ved ikke, hvad militæret idag bruger til styring af f.eks. droner; men de er ialtfald ikke bare lige at jamme, og sikkerhedssystemer til tog burde efter min mening bruge noget tilsvarende.

Hvis man kan bygge en modtager til skidtet så kan man også bygge en jammer. Og "militæret" er ikke immune for jamming etc. Læs fx. historien om hvordan Iran fik en amerikansk drone til at lande her. Der er også bunker af historier om GPS spoofing.

Det er lige netop det punkt - evnen til at modtage et svagt signal på trods af et kraftigt, forstyrrende signal - der skiller professionelle (militær)modtagere fra kineserskrot og billige SDR-chips

Når vi snakker sikkerhed i tog så kan modstanderen godt stå med "militært udstyr". Hele din forklaring viser ret godt hvorfor hardware folk skal holde sig langt væk fra at lave kommunikationsprotocoller: De tror at deres hardware er unik og at ingen kan lave det samme. Den slags fejler altid. Den eneste måde at beskytte kommunikation er enten ved at beskytte mediet (fx. kabler der er placeret i et beskyttet miljø eller en betroet kurer) eller med kryptografi.

I øvrigt var det dig der blandede GPS ind i historien. Som sagt: GPS kan spoofes og i øvrigt er præcisionen ikke altid høj nok til at sige hvilket af to parallele spor det står på.

16
20. juli 2021 kl. 13:43

Hvis du sender et kraftigt 5 GHz signal imod et tog eller en base, så overstyrer du modtageren og systemet stopper.

Det er lige netop det punkt - evnen til at modtage et svagt signal på trods af et kraftigt, forstyrrende signal - der skiller professionelle (militær)modtagere fra kineserskrot og billige SDR-chips. Nu er jeg fra rørtiden og kan bl.a. huske blandere med beam-deflection tubes ( https://commons.wikimedia.org/wiki/File:Beam_Deflection_Tube_basic_circuit.png ), som kunne modtage adskillige volt uden at overstyres, og tilsvarende kan man formodentlig opnå med nyere switch-mode blandere; men det bliver selvfølgelig svært ved 5-6 GHz, hvilket er endnu en årsag til at reducere frekvensen.

15
20. juli 2021 kl. 13:20

Du kan måske med en retningsantenne jamme accesspoints, så de ikke modtager noget - ikke mindst hvis systemet er WiFi lignende; men målet med at udvikle spread spectrum CDMA til militærbrug var jo netop at udvikle systemer, der er betydelig sværere at jamme.

Hvis du sender et kraftigt 5 GHz signal imod et tog eller en base, så overstyrer du modtageren og systemet stopper. Givet at man kan komme helt tæt på begge dele, eksempelvis på en station, så kan jeg ikke se at det er muligt at sikre imod jamming.

Men du kan også afspore toget ved at pille ved skinnerne. Det skal selvfølgelig ikke være alt for nemt men pas på med at tro at en jernbane kan sikres 100%. Så længe det kun betyder at systemet standser, så lever vi nok med det.

14
20. juli 2021 kl. 12:50

En ondsindet person kan placere en jammer i toget og så kan han ellers sende "telegrammer" ud med fortløbende løbenummer fra en anden lokation.

Hvordan vil du jamme udsendelse af signaler fra toget, hvis det sker fra en antenne på taget, som jo er af metal? Vil du kravle derop under køreledningerne og installere udstyr, og hvordan vil du styre, at alle andre telegrammer end positionsangivelserne ikke også bliver blokkeret, da jammingen ellers hurtigt vil blive opdaget.

Du kan måske med en retningsantenne jamme accesspoints, så de ikke modtager noget - ikke mindst hvis systemet er WiFi lignende; men målet med at udvikle spread spectrum CDMA til militærbrug var jo netop at udvikle systemer, der er betydelig sværere at jamme. Jeg ved ikke, hvad militæret idag bruger til styring af f.eks. droner; men de er ialtfald ikke bare lige at jamme, og sikkerhedssystemer til tog burde efter min mening bruge noget tilsvarende.

CRC er fint til at detektere transmissionsfejl. Men det kan ikke bruges til at beskytte mod spoofing.

Det gør jeg da heller ikke. Jeg er bare (i modsætning til alle andre) så smart, at jeg udnytter, at telegramløbenummeret er kendt og derfor kan inkluderes i CRC check på samme måde som en fast eksponent, så det ikke kræver yderligere bit. På den måde kan Max-i f.eks. sende en 26-bit fixed point procesværdi incl. en 12 bit identifier med en 7-bit Hamming kode til bekyttelse mod maskering, en 20-bit CRC check og et 7-bit telegramløbenummer i kun 7 bytes. Effektivitet er langt bedre end hastighed!

13
20. juli 2021 kl. 12:27

Også ud fra dette synspunkt er det ikke særlig smart at polle, for så skal der regnes med det dobbelte propagation delays plus den tid, det tager at sende selve pollet og vende kommunikationsretningen.

Det er tovejskommunikation. Toget skal også have besked hver 400 ms ellers nødbremser det. Base til tog fungere implicit som polling og som synkronisering hvis der bruges timeslots.

Jeg er enig i at beskederne må være tilstrækkeligt korte og båndbredden tilstrækkeligt høj, til at man kunne lave det må mange smarte måder. Men du behøver ikke blande GPS og lignende ind i det.

De kunne køre DAB på base til tog, dvs alle baser sender en komplet opdate af hele banen hvert 400 ms og de sender det samme signal på samme frekvens. Men det gør de næppe :-)

12
20. juli 2021 kl. 12:11

Nej, man behøver bare et telegramløbenummer, som jeg skriver - plus selvfølgelig en tidssynkronisering ved time division multiplex.

Din sikkerhedsmekanisme svarer til den der blev brugt til bilnøgler tidligere. Det giver ikke den nødvendige sikkerhed til et sikkerhedssystem (eller til en billås). En ondsindet person kan placere en jammer i toget og så kan han ellers sende "telegrammer" ud med fortløbende løbenummer fra en anden lokation. Så stopper toget (hvis det ikke modtager signaler fra resten af togene) mens resten togene tror at toget fortsætter. Kollision er sandsynligt.

CRC er fint til at detektere transmissionsfejl. Men det kan ikke bruges til at beskytte mod spoofing.

11
20. juli 2021 kl. 11:46

Set i lyset af at systemet bruges til sikkerhed så er det nødvendigt med en authentikeringsmekanisme sådan at alle ikke bare kan begynde at sende S-togs positionsbeskeder ud i æteren.

Nej, man behøver bare et telegramløbenummer, som jeg skriver - plus selvfølgelig en tidssynkronisering ved time division multiplex.

Hvis f.eks. et tog har sendt telegram nr. 30, vil access-punkterne forvente, at næste telegram fra dette tog har nr. 31. Hvis access-punkterne i stedet modtager f.eks. telegram nr. 32, ved man, at et telegram er mistet, hvilket man måske også kan se af, at der er gået mere end 400 ms, og hvis en hackerenhed udgiver sig for toget og sender 31, vil man senest 400 ms senere modtage endnu et telegram med nr. 31 fra toget og kan så se, at nogen har prøvet at snyde systemet. Det er et kendt princip til sikkerhedssystemer og benyttes f.eks. i min feltbus Max-i. Her tælles fra 0 op til 127, hvorefter telegramnummeret wrapper rundt til 28, så et reset detekteres (0-27 sendes normalt aldrig igen), og tællelængden (100) ikke er 2^N, hvilket beskytter mod dekoder- og tællefejl. Da telegramløbenummeret er kendt information, er den i Max-i integreret i CRC-checket og kræver derfor ikke flere bytes.

10
20. juli 2021 kl. 11:06

For det andet virker den krævede båndbredde helt ude i skoven. En GPS position består at 8 bytes, så hvis 135 S-tog skal sende sin position 2,5 gange pr. sekund, kræver der kun en payload på 21,6 kbit/s.

Set i lyset af at systemet bruges til sikkerhed så er det nødvendigt med en authentikeringsmekanisme sådan at alle ikke bare kan begynde at sende S-togs positionsbeskeder ud i æteren.. Så der kan du smide 256 bits oveni per message ... mindst. Læg så oveni at man givetvis også sender data om hastighed, spor nummer, etc. Og så ville det være ganske håbløst at designe systemet sådan at det kun lige har nok kapacitet.

9
20. juli 2021 kl. 09:43

Baseskift inkluderer også frekvensskift.

Det vil da ikke være særlig smart.

Hvis man, som her, benytter 6 GHz, som ikke rækker særlig langt, og kun har behov for transmission af ca. 50 kbit/s total, vil langt det mest optimale da være time division multiplex på samme frekvens. At bruge flere frekvenser vil da være spild af "kostbar" båndbredde.

Har man, som her, desuden hele 50 MHz til rådighed, vil Code Division Multiple Access (CDMA), som f.eks. benyttes på 3G mobiltelefoner, nok være det optimale. Derved får man en spread spectrum modulation, som er meget vanskelig at jamme. CDMA blev netop udviklet at det amerikanske militær under Vietnamkrigen og er altså et eksempel på den form for militærkommunikation, som jeg ville anvende for at gøre systemet så robust mod jamming, som muligt. Med CDMA behøver hver enhed kun at sende omkring 50 bit/s (ca. 20 bit hvert 400 ms), hvilket giver mulighed for en meget lang og dermed robust code. Med en hastighed på kun 50 bit/s kan man faktisk kommunikere med den anden side af jordkloden med ganske få watt, som radioamatørernes FT8 er et godt eksempel på (benytter dog GFSK og ikke CDMA).

Medmindre du forestiller dig at køre på en radio der rækker hele Storkøbenhavn, så vil du ende med en variant af et sådant system.

Hvorfor det?

Det, der sætter begrænsningen i rigtig mange kommunikationssystemer incl. den feltbus (Max-i), som jeg arbejder med, er propagation delay. Det betyder, at jo langsommere, man kører, jo længere kan kommunikationen række. Da man her kun har behov for omkring 50 kbit/s ved time division multiplex for 135 tog, kan man sagtens række f.eks. +/-20 km til og fra ét fælles accesspoint, for det nødvendige guard-interval mellem telegrammerne skal blot være minimum 67 us pr. enhed og altså mindst 9 ms pr. 400 ms. Også ud fra dette synspunkt er det ikke særlig smart at polle, for så skal der regnes med det dobbelte propagation delays plus den tid, det tager at sende selve pollet og vende kommunikationsretningen.

8
19. juli 2021 kl. 20:34

Desuden vil et poll-system indebære, at alle accesspoints skal polle alle tog hver 400 ms, med mindre man benytter tidligere viden om togenes position til kun at lade de nærmeste accesspoints gøre det,

Det er et system der holder styr på togenes position til central. Det ville være mærkeligt hvis ikke toget er knyttet til nærmeste base med handover til næste base når det når forudbestemte positioner. Baseskift inkluderer også frekvensskift.

Medmindre du forestiller dig at køre på en radio der rækker hele Storkøbenhavn, så vil du ende med en variant af et sådant system.

7
19. juli 2021 kl. 18:07

Det er jo trivielt i et system med styrede basestationer. De poller bare togene.

Det er ikke det indtryk, man får af denne bemærkning:

Denne type lokationsbeskeder sendes med 400 millisekunders mellemrum.

altså sendes og ikke polles.

Desuden vil et poll-system indebære, at alle accesspoints skal polle alle tog hver 400 ms, med mindre man benytter tidligere viden om togenes position til kun at lade de nærmeste accesspoints gøre det, hvilket så kræver en omfattende styring, og uanset hvad, man gør, vil en masse information være spildt, så den nødvendige båndbredde let kan blive 10-100 gange større, end hvis togene selv tager initiativ til at sende.

Med en nødvendig båndbredde på kun 50-100 kbit/s for alle tog tilsammen må det simpleste da være time division multiplex f.eks. tidssynkroniseret af GPS, hvor hvert tog blot sender efter tur i deres timeslot (round-robin), og data fra alle access points så blot adderes sammen. Det gør det også muligt at benytte et telegramløbenummer, så der ikke kan indsættes eller fjernes telegrammer, uden at det opdages.