HNHacker News
TopNewBestAskShowJobs

Const-me

6,400 karma · joined March 2, 2015

meet.hn/city/42.4303762,18.6988104/Tivat

http://const.me/

submissionscomments
Const-me··on Fine dining restaurants researching guests to make their dinner unforgettable
The last few times I reserved a table at a restaurant, I only gave my first name. They never asked for my full name, would be hard for them to find me on social media. However, I'm an immigrant with a locally uncommon first name, YMMV.
Const-me··on 7-Zip for Windows can now use more than 64 CPU threads for compression
> other systems had been exceeding 64 cores since the late 90s.

Windows didn’t run on these other systems, why would Microsoft care about them?

> x86 arguably didn't ship >64 hardware thread systems until then because NT didn't support it

For publicly accessible web servers, Linux overtook Windows around 2005. Then in 2006 Amazon launched EC2, and the industry started that massive transition to the clouds. Linux is better suited for clouds, due to OS licensing and other reasons.

Const-me··on 7-Zip for Windows can now use more than 64 CPU threads for compression
The NT kernel dates back to 1993. Computers didn’t exceed 64 logical processors per system until around 2014. And doing it back then required a ridiculously expensive server with 8 Intel CPUs.

The technical decision Microsoft made initially worked well for over two decades. I don’t think it was lame; I believe it was a solid choice back then.

Const-me··on A compact bitset implementation used in Ocarina of Time save files
In C++, std::vector<bool> does pretty much the same thing under the hood.

Sadly, C++ standard library API designers made it impossible to directly access the array of integers stored inside std::vector<bool>. This made serialization/de-serialization of these vectors very inefficient, sometimes prohibitively so.

Const-me··on SIMD.info – Reference tool for C intrinsics of all major SIMD engines
The ISA extension tags are mostly incorrect. According to that web site, all SSE2, SSE3, SSSE3, and SSE4.1 intrinsics are part of SSE 4.2, and all FMA3 intrinsics are part of AVX2. BTW there’s one processor which supports AVX2 but lacks FMA3: https://en.wikipedia.org/wiki/List_of_VIA_Eden_microprocesso...

The search is less than ideal. Search for FMA, it will find multiple pages of NEON intrinsics, but no AMD64 like _mm256_fmadd_pd

Const-me··on I'm dialing back my LLM usage
I’m using ChatGPT (enterprise version paid by my employer) quite a lot lately, and I find it a useful tool. Here’s what I learned over time.

Don’t feed many pages of code to AI, it works best for isolated functions or small classes with little dependencies.

In 10% of cases when I ask to generate or complete code, the quality of the code is less than ideal but fixable with extra instructions. In 25% of cases, the quality of generated code is bad and remains so even after telling it what’s wrong and how to fix. When it happens, I simply ignore the AI output and do something else reasonable.

Apart from writing code, I find it useful at reviewing new code I wrote. Half of the comments are crap and should be ignored. Some others are questionable. However, I remember a few times when the AI identified actual bugs or other important issues in my code, and proposed fixes. Again, don’t copy-paste many pages at once, do it piecewise.

For some niche areas (examples are HLSL shaders, or C++ with SIMD intrinsics) the AI is pretty much useless, probably was not enough training data available.

Overall, I believe ChatGPT improved my code quality. Not only as a result of reviews, comments, or generated codes, but also my piecewise copy-pasting workflow improved overall architecture by splitting the codebase into classes/functions/modules/interfaces each doing their own thing.

Const-me··on Framework Laptop 12 review
Couple months ago, I have replaced 3.5 years old HP Probook with XMG EVO 14. Specifically, I have ordered a configuration with Ryzen 7 8845HS, 64GB DDR5-5600, and no disks because I reused 4TB WD Red SN700 from the old laptop, and still have the second M2 2280 slot free should I need more storage.

Pretty good laptop, the screen is great even, colour-calibrated 2880×1800 IPS configurable to 60 Hz refresh rate. However, the up/down arrow keys are not full size, their height is smaller.

Const-me··on Framework Laptop 12 review
> which Intel or AMD cpu can be run fanless and perform well?

For example, AMD Ryzen 7 8840U or 7840U can be configured for the same 15W TDP as Apple M1. At 15W, the overall performance going to be about the same as M1.

Const-me··on Cheap yet ultrapure titanium might enable widespread use in industry (2024)
I think you made a mistake converting units, 28.9 USD/kg = $28900 per ton.
Const-me··on Top researchers leave Intel to build startup with 'the biggest, baddest CPU'
CPUs can’t do that, but legacy is irrelevant. They just don’t have enough parallelism to leverage all these extra transistors. Let’s compare the 486 with a modern GPU.

Intel 80486 with 1.2M transistors delivered 0.128 flops / cycle.

nVidia 4070 Ti Super with 45.9B transistors delivers 16896 flops / cycle.

As you see, each transistor became 3.45 times more efficient at delivering these FLOPs per cycle.

Const-me··on Machine Code Isn't Scary
I think writing assembly indeed offers no benefit for most developers. However, being able to read and understand assembly is generally useful.

Enables debugging binaries and crash dumps without complete source codes, like DLLs shipped with Windows or third-party DLLs. Allows to understand what compilers (both traditional and JIT) did to your source codes, this is useful when doing performance optimizations.

Const-me··on Writing your own C++ standard library part 2
> because of the 16-bit character type

That type is not for characters anymore; all these languages treat these values as UTF-16 units. Unlike C++, their standard libraries provide functions to convert strings between UTF-8 and UTF-16, apply Unicode normalization, decode strings into a sequence of code points, etc.

> That's what iostreams are

iostreams tried to implement binary streams, text streams, and object formatting with the same API. Predictably failed all these tasks, the features are too different. A minimalistic C++ API for a stream of bytes might look something like that:

    struct iStream
    {
        virtual ~iStream() { }
        virtual void read( std::span<uint8_t> buffer ) = 0;
        virtual void write( std::basic_string_view<uint8_t> buffer ) = 0;
    };
> result in developers making software that doesn't work like users of the OS expect

Can you elaborate? When I write string content = File.ReadAllText( path ) in C#, the standard library does exactly the same thing as some C++ library could do: open file for read access, read it to the end, and because C# strings are UTF-16 convert the bytes from UTF-8 to UTF-16.

> Async interfaces are all the rage these days. Meanwhile browsers have moved from TCP to QUIC

I think both points are exotic stuff. Not sure I would want to see them in C++ standard library. Also going to be hard to design a useful platform-agnostic abstractions. OTOH, Unicode strings, file systems, and streams of bytes are literally everywhere in software.

Const-me··on Writing your own C++ standard library part 2
> not something that can be supported in a standard library that cares about long-term backwards compatibility

Standard libraries of Java, JavaScript, and C# are counter-examples.

> you can just use that from C++ if you want to

Technically, C++ standard could feature an abstract interface for a stream of bytes. Would be useful not only for TCP sockets, also for files and pipes.

BTW I’ve been programming C++ for living for decades now, and I never saw production code to use C++ <iostream> header. Instead, C++ developers I worked with have been using either <cstdio> or OS-specific APIs.

> applications are better off handling the differences directly

Many other languages have managed to design high-level platform agnostic abstractions over these things, and implemented them in the standard libraries.

> reserved for truly ossified OS interfaces

By now this applies to files, file systems, pipes, and TCP sockets. While there’re some features hard to abstract away (examples include controlling file permissions, and probably asynchronous I/O), many real-world applications don’t need them. They just need basic stuff like read and write bytes from binary streams, concatenate paths, create/open/delete files, listen and accept TCP sockets.

Const-me··on Writing your own C++ standard library part 2
That particular class doesn’t depend on the COM-related pieces of the ATL library. It can be used in any C++ project which targets windows desktop platform. I think since VS2015 ATL is available even in the freeware community edition of the IDE. Before that, it required a commercial edition.

About non-Unicode WinAPI functions, I don’t use them at all in the software I’m developing, nor the TCHAR conditional typedef. VC++ compiler defines wchar_t as a built-in type for the UTF16 strings used in WinAPI functions.

Const-me··on Writing your own C++ standard library part 2
I would not call that example production quality code.

CreateFileA API thing is only available for compatibility with prehistoric software written for Win9x from the nineties. Also, the SDK comes with CAtlFile class which wraps CreateFileW / ReadFile / CloseHandle and guarantees closing handle in the destructor.

They are using a raw pointer in OMMSet structure which leaks memory. I would replace the raw pointer with std::unique_ptr<D3D12_RAYTRACING_OPACITY_MICROMAP_HISTOGRAM_ENTRY[]>

As for the _alloca, I think it’s OK however I usually assert() the size being allocated is reasonable, like under 256kb.

Const-me··on Writing your own C++ standard library part 2
> probably one of the best algorithms and containers libraries in any language

Mostly agree about the algorithms. Another good thing in C++ are low-level mathematic parts of the standard library in <cmath> and <complex>.

Containers are OK, but neither usability nor performance are IMO great. Node-based containers like red-black trees and hash maps come with a contract which says pointers are stable, by default this means one malloc() per element, this is slow.

However, there’re large areas where C++ standard library is lacking.

File I/O is questionable to say the least. Networking support is missing. Unicode support is missing, <codecvt> deprecated in C++17 because they found out it no longer implements current Unicode standard and instead of fixing the standard library they dropped the support. Date and calendars support only arrived in C++/20. No built-in way to represent money amount, e.g. C# standard library has fixed-size 16 bytes type for decimal floating-point numbers, Java standard library has arbitrary-precision integers and decimals.

Const-me··on On File Formats
Good article, but I’d add one more paragraph.

If your data format contains multiple streams inside, consider ZIP for the container. Enables standard tools, and libraries available in all languages. The compression support is built-in but optional, can be enabled selectively for different entries.

The approach is widely used in practice. MS office files, Java binaries, iOS app store binaries, Android binaries, epub books, chm documentation are all using ZIP container format.

Const-me··on Disabling kernel functions in your process (2009)
Cool trick, but I wouldn’t do that for the use case.

The use case they had is saving minidumps when the app crashes. Windows error reporting OS component is flexible enough to support the feature without hacks, they just need to write couple values to registry in the installer of their software. See details on per-application settings in that article: https://learn.microsoft.com/en-us/windows/win32/wer/collecti...

If they want better UX and/or compress & uploads the dump as soon as the app crashes (as opposed to the next launch of the app) – I would solve by making a simple supervisor app which launches the main binary with CreateProcess, waits for it to exit, then looks for the MainApp.exe.{ProcessID}.dmp file created by that WER OS component.

Const-me··on Making video games (without an engine) in 2025
There’s a recent promising development relevant to the GC pause issue. It seems couple weeks ago some smart developer working for Microsoft has made a version of GC called “Satori” which pretty much solved these GC pauses for many real-world use cases.

An overview article: https://blog.applied-algorithms.tech/a-sub-millisecond-gc-fo...

Long discussion thread with many graphs with measurements: https://github.com/dotnet/runtime/discussions/115627

I don’t yet have hands-on experience with that Satori GC, though.

Const-me··on Flattening Rust’s learning curve
> on some workloads, I found LTO to be a requirement for C code to match C# performance

Yeah, I observed that too. As far as I remember, that code did many small memory allocations, and .NET GC was faster than malloc.

However, last time I tested (used .NET 6 back then), for code which churches numbers with AVX, my C++ with SIMD intrinsics was faster than C# with SIMD intrinsics. Not by much but noticeable, like 20%. The code generator was just better in C++. I suspect the main reason is .NET JIT compiler doesn’t have time for expensive optimisations.

Const-me··on Flattening Rust’s learning curve
> quite a similar model

Yeah, and that model is rather old: https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule In practice, complex software systems have been written in multiple languages for decades. The requirements of performance-critical low-level components and high-level logic are too different and they are in conflict.

> you give the compiler an opportunity to optimise across those unsafe usages

One workaround is better design of the DLL API. Instead of implementing performance-critical outer layers in C#, do so on the C++ side of the interop, possibly injecting C# dependencies via function pointers or an abstract interface.

Another option is to re-implement these smaller functions in C#. Modern .NET runtime is not terribly slow; it even supports SIMD intrinsics. You are unlikely to match the performance of an optimised C++ release build with LTO, but it’s unlikely to fall significantly short.

Const-me··on Flattening Rust’s learning curve
I don’t use C++ for most of my applications. I only use C++ to build DLLs which implement CPU-bound performance sensitive numeric stuff, and sometimes to consume C++ APIs and third-party libraries.

Most of my applications are written in C#.

C# provides memory safety guarantees very comparable to Rust, other safety guarantees are better (an example is compiler option to convert integer overflows into runtime exceptions), is a higher level language, great and feature-rich standard library, even large projects compile in a few seconds, usable async IO, good quality GUI frameworks… Replacing C# with Rust would not be a benefit.

Const-me··on Flattening Rust’s learning curve
Interestingly, CPU-bound high-performance systems are also incompatible with Rust’s model. Ownership for them is unambiguous, but Rust has another issue, doesn’t support multiple writeable references of the same memory accessed by multiple CPU cores in parallel.

A trivial example is multiplication of large square matrices. An implementation needs to leverage all available CPU cores, and a traditional way to do that you’ll find in many BLAS libraries – compute different tiles of the output matrix on different CPU cores. A tile is not a continuous slice of memory, it’s a rectangular segment of a dense 2D array. Storing different tiles of the same matrix in parallel is trivial in C++, very hard in Rust.

Const-me··on Flattening Rust’s learning curve
> I've been using it in C#

One reason why async-await is trivial in .NET is garbage collector. C# rewrites async functions into a state machine, typically heap allocated. Garbage collector automagically manages lifetimes of method arguments and local variables. When awaiting async functions from other async functions, the runtime does that for multiple async frames at once but it’s fine with that, just a normal object graph. Another reason, the runtime support for all that stuff is integrated into the language, standard library, and most other parts of the ecosystem.

Rust is very different. Concurrency runtime is not part of the language, the standard library defined bare minimum, essentially just the APIs. The concurrency runtime is implemented by “Tokio” external library. Rust doesn’t have a GC; instead, it has a borrow checker who insists on exactly one owner of every object at all times, makes all memory allocations explicit, and exposed all these details to programmer in the type system.

These factors make async Rust even harder to use than normal Rust.

Const-me··on C is not a low-level language (2018)
> it is possible to make C code run quickly but only by spending thousands of person-years building a sufficiently smart compiler

Just because some of the C++ code I write heavily relies on ISA-specific SIMD intrinsics doesn’t replace the language with some other one, it’s remains to be C++. Compared to solving the general problem by making a sufficiently smart automatically vectorizing C compiler, learning SIMD intrinsics is way more manageable.

BTW, a few years ago I wrote an article about SSE 1-4 and AVX 1-2 ISA extensions, as exposed to C and C++ languages: http://const.me/articles/simd/simd.pdf

Const-me··on I built a native Windows Todo app in pure C (278 KB, no frameworks)
> such as time.h and string.h

In Windows, the APIs provided by the OS are IMO better than these C standard headers.

WinAPI date/time is more precise, the kernel keeps int64 number of 100 nanosecond ticks. WinAPI supports arbitrary timezones, has functions to convert between timezones, has functions to deal with daylight saving.

About strings, WinAPI can convert strings between encodings, case-insensitive comparisons (including a version to use arbitrary locale), Unicode normalization, etc.

Const-me··on Rust’s dependencies are starting to worry me
The libraries you listed are too specialized. And they require integration with asset pipeline which is well outside of scope of a programming language.

As for the generic things, I think C# is the only mainstream language which has small vectors, 3x2 and 4x4 matrices, and quaternions in the standard library.

Const-me··on My stackoverflow question was closed so here's a blog post about CoreWCF
The .NET runtime is cross-platform, the lower level asp-net infrastructure is included in the runtime. The higher level CoreWCF RPC library OP uses is written fully in C#. I would expect it to run in all environments supported by the .NET runtime.

Personally, I have reproduced the bug on Windows 10 running on AMD64 processor. BTW, the code in the question only communicates to localhost address i.e. doesn’t need any networking on the computer.

Const-me··on My stackoverflow question was closed so here's a blog post about CoreWCF
> because they're terribly asked and probably duplicates

Not all questions which seem duplicate to a non-expert are actual duplicates. An example question which took 2 lines to answer, then a page of text in that answer to restore the question after being closed as a duplicate: https://stackoverflow.com/q/65025858/

Const-me··on My stackoverflow question was closed so here's a blog post about CoreWCF
Almost any hardware, .NET runs on x86, AMD64, ARMv7 and ARM64 processors. Almost any desktop or server OS, .NET runs on reasonably modern versions of Windows, Linux and MacOS.

The complete source code of the server is in the question.

← PreviousPage 4 of 34Next →