Hacker Newsnew | past | comments | ask | show | jobs | submit | RandomOnyx's commentslogin

Decent ones do. .NET's JIT has historically (before ryujit especially and tbh I haven't looked at .NET much in the past decade) not been decent, general statements about decent compilers never applied to it. It has been playing catch-up lately but apparently it still has a ways to go.


That is absolutely not true. Not historically, and not now. .NET's JIT has always been very good, bar a few qualifying statements.

It used to be based on MSVC, with the most expensive optimizations trimmed, things like loop hoisting, devirtualization, generally ones with long runtimes, or ones that required whole program visibility.

But otherwise it was competent, if you wrote code aware of these limitations, it could get very close to even C++, and even on naive code, it was always very competitive (with strange wildcards, that if you used raw pointers, which are an obscure C# feature, you could get code to be even faster, due to the compiler's heritage).

It also helped, that due to MS's nature; C# was meant to be used with MS frameworks, written by people who were aware of the compiler's quirks, which you could learn if you looked at these codebases.

Sure if yo measure against LLVM-compiled static languages, it falls short in certain scenarios, but it's been soldily in the pack of other GC languages like Java or Go, and always has been.


There's an experiment to create an LLVM-based Native AOT tool chain. I sincerely hope they work on this properly, so that we can have a properly optimized AOT. But I'm not sure if it will end up with less quirks.

https://github.com/dotnet/runtimelab/tree/feature/NativeAOT-...


Thanks for that. I had definitely noticed that the .NET JIT wasn't doing loop hoisting. And that you could get close to C/C++ performance if you did loop hoisting manually. It's useful to get some insight on .NET's actual optimization philosophy.


Only the ia64 version of the jit was based on msvc. And older versions of aot mode. Not the more typical jit targets.

I believe the new enabling technology for better codegen is tiered compilation, which has only been around for a couple years.


The old JIT was a fork of a pared-back version of MSVC; this was for all platforms, except the .NET Compact framework, which was for embedded stuff, and it was its own fork.

There were other weird things like C++/CLI which was a full-fat MSVC fork used to compile C++ either into .NET IL or x86 code which could be embedded into .NET assemblies, but could still call into .NET code.

But what most people think of as .NET (Framework) was definitely using the old MSVC-based JIT


For what it’s worth, C++/CLI is not a fork, but a feature of the VC++ compiler, which still exists and supports the latest .NET versions, with the important caveats that it’s neither cross-platform nor open source.

I, for one, would love to have a cross-platform, open source C++/CLI compiler, because there is no more convenient way to consume nontrivial C++ APIs (and buggy, poorly-specified COM APIs only documented by C++ example code) in .NET.


RyuJIT has had tiered compilation for about 10 years.


Ehhhhhhh I thought it was a bit of a mishmash, at least before ryujit?

i.e. I think the x64 framework compiler was based on MSVC, but the x86 was a bit of a different beast. That was part of why they did RyuJit in the first place, to help unify the JITs between the large divergence in how they worked [0].

One big thing being, AFAIK the old 32 bit JIT would never use SSE2 outside of some block copy type stuff. They assumed a safe baseline for most other instructions and stuck with that (although, there can be good reasons for this, e.x. consistency with x87 behavior.)

Will also add that the old x64 compiler sometimes really did do some questionable stuff, i.e. when we flipped things to use it we never really saw a perf benefit even when dealing with larger datatypes/etc that should have seen a benefit from wider registers.

RyuJit definitely has fixed that, but... again, the past is a bit hazy.

[0] - https://devblogs.microsoft.com/dotnet/ryujit-the-next-genera...


They have been improving, this is one area however where those C# vs Java flamewars kind of miss out.

While C# the language has much more goodies than Java the language, Java the platform has had much better options than the CLR, because it has been mostly Microsoft and Mono (nowadays almost gone after the acquisition), whereas the Java ecosystem has a plethora of implementations, each one wiht their JIT and GC implementations, even AOT caches since almost three decades now.

Thankfully the outcome of Project Midori, and the whole Secure Future Initiative , has had the side effect of Microsoft becoming more serious about .NET performance, instead of always outsourcing performance workloads to C++ and COM.


It never was a priority I believe. As opposed to C, the main target audience of C#/.NET has always been LOB CRUD app shops.


Kind of, us users of .NET would have liked a Delphi, VB 6 kind of attention to performance, however for many years, Microsoft management had exactly that attitude, expecting that anyone that cared about performance would be writting COM in C++, or DLLs, and consuming those artifacts from .NET.

Finally they changed their approach to .NET, besides Midori, SFI that I mention on a sibling comment, certainly also due to Go and Rust competition.

Note how Azure nowadays does most of their open source contributions in Go and Rust, the rewrites that completly ignored .NET, while the team mentions lack of adoption on .NET related podcasts.


They had a few 'squirrel' moments.

Silverlight comes to mind, Also the fever dream that was '.NET micro'. I might still have my NetDuino somewhere...

> the main target audience of C#/.NET has always been LOB CRUD app shops.

I do think this has changed over time. There's definitely been improvements to the overall ecosystem from game developers (Cysharp being the most prolific) via both libraries and feedback around the BCL/JIT/etc.


Reading between the lines, I blame essentially the opposite thing: too much neoliberalism, preventing governments from enacting effective industrial policy (for ideological reasons, not as a choice for a plausible pathway to the desired outcomes). There is some but too little and too indirect. The focus is more on doing as little as possible than on really doing things, on giving permission and as-small-as-possible incentives for things to be done rather than causing them to be done (let alone straight up doing them - neolibs recoil in horror).

That's how I see it anyway, almost everyone else wants to double down on neoliberalism ie the negation of industrial policy. Except perhaps Frank Heemskerk from the article, who mentions wanting governments to create demand for made-in-europe chips so that fabs get built to supply that demand.


We had Ice Lake and Rocket Lake too, they seem to have disappeared from the collective memory


Their successors had more tangible performance improvements in everyday applications, so yes they were quickly forgotten. Also, it was a reduction in max core count from 10 to 8, intel changes sockets too often, and 14nm+++++.


I have an ice lake laptop with avx512. The problem is that intel only made about 15 of them because their 10nm process was a disaster.


And nobody talks about the Xeon Phi anymore…


Does rdrand32 and then taking the lowest 16 bits of its result yield any zeroes?

Basically I'm wondering if it's a bug in the version of the instruction that writes to a 16-bit reg, or a bug in the underlying RNG


Yes it does. rdrand32()%65535 was my first attempt, and generated zeroes at about the expected rate, that's why I initially erroneously thought my CPU did not have this problem.


You should be using &0xFFFF for masking. Your mod is off by 1 too.


You're right, the code was correct but my comment above is wrong.


How about* rdrand32()%65536? Taking the remainder by 65535 doesn't take the lowest 16 bits after all

*: missed a word the first time around


(in case it matters, I tried z80)

I see we have #include as usual, but how do I add files? Wasn't clear to me.

Also I would like to download the assembled & linked binary. That kind of usage may not be what you're going for, but then I can run it on an active device too, not just in the emulator.


The app was mostly made to run small snippets to teach assembly but I'm working on adding multiple source files right now and it's almost finished!

The long term goal was to also add "compile from C" which shows the C to assembly compilation, which can then be emulated line by line.

About the download of assembled binaries, on the roadmap there is upload and download of binaries so you can disassemble some binary, read the contents, compile programs and download them, the harder part is linking. All assemblers (except m68k) could in theory already export the binary, i just did not add the functionality yet.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: