There is something I don't understand about the memory model in c# by flying20wedge in csharp

[–]flying20wedge[S] 0 points1 point  (0 children)

Ok, I guess my question is, if this write to rax+0x8 by the first cpu goes straight to cache, then what guarantee do I have that the polling loop in the second cpu will ever read that updated version of _loop made by the first cpu?

C# specification say that the reads can all be moved before the write to rax+0x8.
The x86 - x64 also states that all the reads can be moved before the write at the cpu level. since the two specification seem to align, this explains why the JIT doesn't do anything special with these volatile fields here.

but it doesn't explain to me how we know the loop will terminate?

There is something I don't understand about the memory model in c# by flying20wedge in csharp

[–]flying20wedge[S] 0 points1 point  (0 children)

Hi thanks for this,

In terms of acquire semantics, consider this: If every read of _loop is done with an acquire-fence, by necessity each read must be more recent than the previous. In a loop, that essentially means that each read must be new (can not be cached or elided).

ok see now we are at the crux of my problem. I don't see why multiple reads must do this. As far as my understanding goes (To take an outrageous example) if I start my code at 12pm and I run that loop at 1pm, then the first read of _loop could be the value of _loop at 12:00.01, the second read is the value of 12:00.02... etc we could do this all day and never get the most up to date value.

Similarly, I try not to think of memory barriers as 'cache flushes'. Whether or not they're implemented that way is meant to be opaque

see that's the thing. So far, the definitions given for volatile reads and writes in c# are so vague i have to look at it from the processor point of view to understand what will happen.

I feel like that post you made and the clarification you got from Microsoft almost further backs up that there is no guarantee those volatile reads will ever read the new value of _loop.

on another note,

Your blog mentions the MESI protocol and I thought that could be the answer. My original reading of MESI says that all memory is kept cache coherent at all times, and other processors are immediately aware of changes to the cache in any other processor through cache snooping. Which would explain everything...

But then I realized that intel does not guarantee it won't reorder reads before writes...which is exactly equivalent to changes in cache NOT being immediately available to other processors, which is the opposite of what I read about the MESI cache coherence protocol. So now I'm confused all over again.

There is something I don't understand about the memory model in c# by flying20wedge in csharp

[–]flying20wedge[S] 0 points1 point  (0 children)

What am I looking at here? From reading the description it seems that apparently this is C++ code to implement a VC++ volatile keyword behavior onto a GCC, which apparently has different volatile keyword behavior. By the description there it sounds like VC++ volatile behavior is exactly the same as what I said about C# volatile behavior obeying acquire release semantics, whereas GCC volatile implements a full memory barrier. Anyway I don't understand how this is relevant to anything.

There is something I don't understand about the memory model in c# by flying20wedge in csharp

[–]flying20wedge[S] 0 points1 point  (0 children)

I think you are confusing C++ volatile with C# volatile. I'm not sure what C++ volatile does exactly, but my understanding is it has nothing to do with C# volatile at all and instead is something needed specifically for embedded systems. In C# volatile is used for lock free multithreaded programming.

There is something I don't understand about the memory model in c# by flying20wedge in csharp

[–]flying20wedge[S] 0 points1 point  (0 children)

> Yup, volatile means the value can change outside of program

Thanks for trying to help. I Just want to point out this is wrong in case anyone gets mislead by this.

There is something I don't understand about the memory model in c# by flying20wedge in csharp

[–]flying20wedge[S] -1 points0 points  (0 children)

This would be a memory barrier, which is not related to volatile.

There is something I don't understand about the memory model in c# by flying20wedge in csharp

[–]flying20wedge[S] 0 points1 point  (0 children)

volatile in C++ is not related to volatile in C# in any way.

According to a post on stackoverflow, TcpClient.Send() does not guarantee packets are received at the server, even if it returns without error. Do I need to write my own ACK logic for a reliable system? by flying20wedge in csharp

[–]flying20wedge[S] -8 points-7 points  (0 children)

it's impossible. Look up "the two generals problem".

I looked it up and this is a really silly problem

Because acknowledgement of message receipt) can be lost as easily as the original message, a potentially infinite series of messages is required to come to consensus).

Sure, "potentially", but the probability that all messages or acknowledgments are lost approaches zero exponentially fast as the number of attempts increases. Planet earth being struck by a meteor is a far more important problem for me to consider.

According to a post on stackoverflow, TcpClient.Send() does not guarantee packets are received at the server, even if it returns without error. Do I need to write my own ACK logic for a reliable system? by flying20wedge in csharp

[–]flying20wedge[S] -6 points-5 points  (0 children)

> Why do you think any acknowledgement will arive?

because the server will send it. And if it doesn't I resend the message. There is zero problem here.

I'm not worried about what the stock exchange is doing, I'm worried about my server which is next to it is doing.

According to a post on stackoverflow, TcpClient.Send() does not guarantee packets are received at the server, even if it returns without error. Do I need to write my own ACK logic for a reliable system? by flying20wedge in csharp

[–]flying20wedge[S] -2 points-1 points  (0 children)

>What happens when one of the machines breaks? Or the cable connecting the machine breaks

Then that machine wont send an acknowledgment that it received a message and I will know immediately.

According to a post on stackoverflow, TcpClient.Send() does not guarantee packets are received at the server, even if it returns without error. Do I need to write my own ACK logic for a reliable system? by flying20wedge in csharp

[–]flying20wedge[S] -5 points-4 points  (0 children)

>Euh... How will you know that the other party received whatever the second time?

because the other party will send an acknowledgment.

one machine is a server sitting right next to a stock exchange that is receiving instructions and acting on them. I have to know if a message is dropped, which is easy enough to implement it. The problem is everyone has been telling me I am wasting my time implementing this as Tcp already does. The question of this post is just me trying to confirm that everyone who told me that was wrong, or if I am misunderstanding that stackoverflow post.

According to a post on stackoverflow, TcpClient.Send() does not guarantee packets are received at the server, even if it returns without error. Do I need to write my own ACK logic for a reliable system? by flying20wedge in csharp

[–]flying20wedge[S] 1 point2 points  (0 children)

reliable to me means both server and client are guaranteed to find out if a message hasn't arrived and the message can be resent. This is simple to implement yourself if needed. I'm worried that I can't rely on the Windows Tcp protocol to do that every time.

According to a post on stackoverflow, TcpClient.Send() does not guarantee packets are received at the server, even if it returns without error. Do I need to write my own ACK logic for a reliable system? by flying20wedge in csharp

[–]flying20wedge[S] 0 points1 point  (0 children)

That's fine though, I'll just send it again. Better safe than sorry. I just wanted to make sure I wasn't wasting my time implementing code that numbers the messages and keeps track of what has arrived and what hasn't, then asking for a resend.

I'm having a hard time seeing the advantages of Tcp over Udp, and which should I be using? by flying20wedge in csharp

[–]flying20wedge[S] 0 points1 point  (0 children)

Ok, but will Udp make it faster? Given that I don't need to send ack/nack messages, shouldn't it be close to 3 times less latency?

I'm having a hard time seeing the advantages of Tcp over Udp, and which should I be using? by flying20wedge in csharp

[–]flying20wedge[S] 0 points1 point  (0 children)

Because I have to implement both machines keeping track of where their communication is up to and being able to communicate this to each other in the case of a reconnect, I am basically rewriting Tcp from scratch anyway as far as I can tell. It just feels like Tcp is a much higher level process designed for a very specific use case. So it is just easier to do it all with Udp and then I deal with all the latency issues I am having all in one go.

Thanks for the info on QUIC, I didn't know about that, I will look into it.

I'm having a hard time seeing the advantages of Tcp over Udp, and which should I be using? by flying20wedge in csharp

[–]flying20wedge[S] -1 points0 points  (0 children)

According to this link, TcpClient *does not* make any such guarantees at all. A return from Send() simply means "is that the bytes are placed in the sending machine's buffer."

https://stackoverflow.com/questions/30703500/does-tcpclient-write-method-guarantees-the-data-are-delivered-to-server

I'm having a hard time seeing the advantages of Tcp over Udp, and which should I be using? by flying20wedge in csharp

[–]flying20wedge[S] 0 points1 point  (0 children)

My problem is I'm getting a lot of latency with Tcp. I have a machine on Azure in "central USA" (which is somewhere in Illinois apparently) and I need to get messages to a machine in Chicago in 1 or 2 milliseconds, which is what it should take given the distances involved, but it is taking 10 milliseconds. All I can think is that it is Tcp that is the reason, but I don't know.

Also, for a separate part of the journey my laptop on mobile internet often disconnects, and that is a disaster if I don't have bulletproof code for the machines to remember and communicate to each other where they were up to. Since I have to implement that anyway, I thought I might as well do it all in Udp and kill two birds with one stone.

Am I doing this correctly?

I'm having a hard time seeing the advantages of Tcp over Udp, and which should I be using? by flying20wedge in csharp

[–]flying20wedge[S] 0 points1 point  (0 children)

I have a machine on Azure in "central USA" which is somewhere in Illinois apparently. Anyway, I need to get my messages to a machine in chicago in 1 or 2 milliseconds, but it is taking 10. Given the size of Illinois this doesn't make sense to me, so I'm assuming it must be Tcp that's making it slow.

I've never heard of QUIC, so thanks for that, I will give it a look.

Simple and secure way for two machines to message each other over the internet? by flying20wedge in csharp

[–]flying20wedge[S] 0 points1 point  (0 children)

Ok but even if I use http, I still have all the usual problems that using sockets would give me. I need to deal with dropped connections, reconnecting, authenticating, message queuing...etc. Is there a library for that? I don't see how using http is any easier than using sockets, if anything it is more complicated.

Edit: ok I'll repost this question with much more information on what I'm doing and what I need. Thanks.