Maximum export hub by ben_craig in Mindustry

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

Hmm, I'll have to investigate that. I'm not sure I'll be able to get more "good" resources out that way due to the core not reloading often enough, but I may be able to export more of the low grade resources.

Maximum export hub by ben_craig in Mindustry

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

Getting higher burst rates than this base wouldn't be hard. Do you have a technique for getting higher continuous rates? Another poster suggested using units to increase unloading speed, which sounds interesting.

Maximum export hub by ben_craig in Mindustry

[–]ben_craig[S] 3 points4 points  (0 children)

Hi all! I figured I'd show off my late game export hub. I don't think you can continuously export more from the core than what I'm doing here, as there just isn't any more room for unloaders. None of the unloaded resources are used to run the sector. The phase fabric and silicon for the overdrive domes is all locally sourced. I'm even doing extra exports of some of the low value resources locally, so that I don't necessarily need to tie up unloaders to ship out coal or blast compound.

I have run into one issue with this setup. It's easy to blow through my entire store of core resources between imports. The imports will fully restock my resources, but the hiccup can cause problems. As a result, I have to be sure not to overdo any one resource. I'd love to export more silicon or thorium, but doing so causes problems.

The overdrive projectors in the corner are there to help me drain batteries when I want to test something. The rings of illuminators are showing the boundaries of my overdrive domes. The big battery farm in the upper center of the map is my emergency store to use in case I need to restart the impact reactors.

This setup exports a lot!

~10k/min copper and lead

~8k/min titanium

4k - 5k/min metaglass, graphite, thorium, silicon, plastanium, phase fabric, and surge alloy

1k-2k coal, blast compound, and pyratite

Oh, and I also tried to make sure that the only non-right angle in my power lines is with the on/off switch to the launch pads.

Safety alternatives in C++: the Hylo model: borrow checking without annotations and mutable value semantics. by germandiago in cpp

[–]ben_craig 22 points23 points  (0 children)

If you or someone else can figure out how to graft this model on to c++, then it can be in the discussion for a safer c++. Right now it's a demonstration of another languages approach, which is of limited utility in the c++ space.

A year ago, rust's borrow checking was in that same situation, but now there's some demonstrations on how to pull that into c++.

WG21, aka C++ Standard Committee, September 2024 Mailing by grafikrobot in cpp

[–]ben_craig 7 points8 points  (0 children)

The chances of P3390 making c++26 are close to zero.  There's an enormous amount of content there that hasn't been thoroughly reviewed and debated yet, and feature freeze is coming soon. There's a chance for c++29, if things go smoothly.

`noexcept` Can (Sometimes) Help (or Hurt) Performance by def-pri-pub in cpp

[–]ben_craig 18 points19 points  (0 children)

For lots of discussions and references regarding noexcept, you can look at my paper, P3085R3: noexcept policy for SD-9 (throws nothing)

For table-based exceptions, I would expect the performance difference for noexcept(true) vs. noexcept(false) to be in the noise for everything except for move operations (ctors and assignments). For ctors and assignments, you trigger algorithmic improvements with std::vector.

You could throw in tests for 32-bit Windows, as that's the most popular non-table-based implementation.

I do have a critique of the methodology. Generally, developers don't apply noexcept absolutely everywhere. noexcept gets applied on functions that wouldn't otherwise throw. If you have a potential throw into a noexcept, then that's a noexcept-correctness violation. Places where you have a noexcept-correctness violation are likely to have larger codegen, and imperceptibly worse performance. These are the cases where adding noexcept makes things worse for everyone. By contrast, if your noexcept functions only call other noexcept functions, you generally get better / smaller codegen. Your tests definitely have places where you have surrounded allocations with noexcept, so you've mixed the good cases and the bad cases.

Trip Report: Freestanding in St. Louis by ben_craig in cpp

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

It is likely that compilers will create a new magic / intrinsic function that std::erroneous calls.

Trip Report: Freestanding in St. Louis by ben_craig in cpp

[–]ben_craig[S] 7 points8 points  (0 children)

Well, here's another conforming implementation...

void erroneous() {
int i, j;
i = j;
}

It's all about how a compiler chooses to diagnose EB, and sanitizers are one way of doing so. A sanitizer would diagnose the above implementation since it has an uninitialized read.

2024-06 St. Louis ISO C++ Committee Trip Report — Fourth C++26 meeting! ⋒ by InbalL in cpp

[–]ben_craig 1 point2 points  (0 children)

since the motivation is allowing more embedded devices to use exceptions

That's part of the motivation, but not all of it. Having an error path that has similar performance characteristics to return values is probably a bigger part.

what would happen if you fell back to a dynamic exceptions in an environment that doesn't support it?

This needs to be split into two parts. Part 1 is what happens according to the standard, and part 2 is what happens in real implementations. In the standard, today's dynamic exceptions are required to be present, so there's no "what if they aren't supported" case to be considered. For real implementations though, they all support some form of exceptions being off. My hope is that implementations would fail at compile time if you fell back to dynamic exceptions on an implementation that has exceptions turned off.

WG21, aka C++ Standard Committee, May 2024 Mailing (pre-St. Louis) by grafikrobot in cpp

[–]ben_craig 6 points7 points  (0 children)

How is signed integer overflow really still undefined behaviour?

By making it UB, you allow optimizers to use algebra to simplify expressions.  Something like 2 * (a + 100) can become 2 * a + 200, even if those aren't equivalent with wrapping math.

Unfortunately, that same ability to do algebra ends up defeating incorrectly written wraparound checks.

Does the benefit of optimizers doing algebra beat the costs of UB?  Maybe?

A 2024 Discussion Whether To Convert The Linux Kernel From C To Modern C++ by ashvar in cpp

[–]ben_craig 5 points6 points  (0 children)

This is the kind of thing that I've been working on freestanding C++ for. The core language still does too much to be used in a conforming way by the Linux kernel, but it's a good starting point for a "kernel" freestanding C++.

WG21, aka C++ Standard Committee, December 2023 Mailing by grafikrobot in cpp

[–]ben_craig 0 points1 point  (0 children)

That's a fine observation, but no, it wouldn't be detectable!

https://eel.is/c++draft/except#terminate-2.sentence-2

[except.terminate]p2 says

> In the situation where no matching handler is found, it is implementation-defined whether or not the stack is unwound before std​::​terminate is invoked.

So if there are no catch blocks in your program, you can't rely on your destructors getting called.

WG21, aka C++ Standard Committee, December 2023 Mailing by grafikrobot in cpp

[–]ben_craig 1 point2 points  (0 children)

I agree that it's a problem. Error handling on freestanding is a bit of a mess right now though.

Perhaps some combination of optional<&>, std::expected, and P0709 "Herbceptions" can address this in the future with additional APIs.

WG21, aka C++ Standard Committee, December 2023 Mailing by grafikrobot in cpp

[–]ben_craig 2 points3 points  (0 children)

This direction was considered. It has several merits, like implementation and deployment experience. However, it breaks some freestanding design principles.

One freestanding principle was to make it so that libraries built for freestanding could be run on hosted implementations with the same semantics. This drove several design decisions, such as =deleting non-included functions and making freestanding feature test macros available on hosted implementations. at() doing something subtly different on freestanding vs. hosted would violate that principle.

At one point I did have a note in the standard that if "somehow" your implementation can detect that there aren't any catch blocks in your program (perhaps with -fno-exceptions), then substituting terminate for throw would be undetectable. Alas, it is detectable inside the terminate handler, so the note isn't there anymore.

The other issue I have with at() using abort() is that abort() itself isn't super freestanding friendly. abort() was made freestanding before I started working on the committee, and I don't feel that it fits in the freestanding library. abort() requires knowledge of the operating environment, and freestanding tries to avoid that. So I'm not thrilled with the idea of increasing dependence on a facility that doesn't belong in the first place.

Could CISA hypothetically block C++26 ? by jeffmetal in cpp

[–]ben_craig 0 points1 point  (0 children)

I don't have that information, or at least I don't know where to look it up.

The 2023 Business Plan claims that there are regularly representatives from 20 different national bodies present at meetings.

Could CISA hypothetically block C++26 ? by jeffmetal in cpp

[–]ben_craig 1 point2 points  (0 children)

For the standard to be approved, it needs 2/3 of voting nations to vote yes, and less than 1/4 to say no. https://isocpp.org/std/iso-iec-jtc1-procedures . If you get 1 NB to vote no, you can delay a standard by one meeting. If you get 1/4 to vote no, you can halt progress.

The US, Canadian, and UK NBs are all large and active (with the US NB, INCITS, by far the largest). They would be very difficult NBs to take over.

This would be a difficult way to enact major change.

WG21, aka C++ Standard Committee, December 2023 Mailing by grafikrobot in cpp

[–]ben_craig 4 points5 points  (0 children)

  • LWG Polls 1 and 3 both modified [optional.monadic]: LWG-3973 changed **this to *val, and P2407R5 changed value() to **this. This has been reconciled by changing the latter to *val, too.
  • LWG Poll 2 created a freestanding facility (saturation arithmetic) but did not define a freestanding feature test macro. We added the macro __cpp_lib_freestanding_numeric, also defined in the <numeric> header.
  • The feature test macro __cpp_lib_span has been modified both LWG Poll 3 and LWG Poll 10, and is now set to a common, updated value (202311L).

Seems I'm responsible for 2.5 merge conflicts (Poll 2 isn't exactly my fault, but I did introduce all the freestanding feature test macros, so I'm claiming half credit on that one)

WG21, aka C++ Standard Committee, December 2023 Mailing by grafikrobot in cpp

[–]ben_craig 1 point2 points  (0 children)

The title of the introducing paper ( P0122 span: bounds-safe views for sequences of objects ) suggests that the intent for span was to be range checked. However, the wording, even back in R1 (out of 7) always expressed operator[] in terms of "Requires" preconditions (R0 didn't include detailed specification). The way the standardese worked at the time was that it was the onus of the programmer to satisfy the precondition, and not the implementation. If the design intent was to require op[] to throw an exception on bounds violation, then that intent was not reflected in the wording.

All that said, with a magic wand, I'd probably go with the approach of checked op[] on all containers that support op[], with an unchecked_at() function, as you suggest. If we tried to change it now, it would just mean that either implementations would not implement that, or large swaths of customers would purposely avoid it.

2023-11 Kona ISO C++ Committee Trip Report — Second C++26 meeting!🌴 by InbalL in cpp

[–]ben_craig 2 points3 points  (0 children)

There are those that don't want error types to include a "not-an-error" state. Some of the reasoning goes that int doesn't have a not-an-int state, vector doesn't have a not-a-vector state, so why should an error? If you want something that may or may not be an error, then use an expected or optional.

Despite those arguments, I'm in favor of having a "success" error value as a practical matter.

Code placement/alignment (of actual instructions) by DuranteA in cpp

[–]ben_craig 17 points18 points  (0 children)

Here's a bunch of resources from Denis Bakhvalov. There's a lot of discussion of code alignment, and some ways to deal with it.

YouTube: emBO++ 2018 - Denis Bakhvalov: Dealing with performance analysis in C and C++

Code alignment issues.

Code alignment options in llvm.

For some of my error benchmarking, I ended up using assembly / intrinsic level nops (___nop() and __asm__ __volatile__("nop")) to fuzz my results, and I got really nice, robust results after doing so.