|
|
Subscribe / Log in / New account

Optimizing for one CPU

Optimizing for one CPU

Posted Jun 10, 2025 23:25 UTC (Tue) by iabervon (subscriber, #722)
Parent article: An end to uniprocessor configurations

I'm a bit surprised, upon thinking about it, that C doesn't have an unsigned 0-bit integer type that you'd use if you set NR_CPUS to 1. It seems to me like a great way of getting code that your compiler can optimize really well: as an lvalue, you can only set it to 0, which doesn't have any effect, and as an rvalue, it's a compile-time constant 0. Then, a ton of code just goes away that would have been necessary if the size wasn't 0.


to post comments

Optimizing for one CPU

Posted Jun 11, 2025 0:24 UTC (Wed) by wahern (subscriber, #37304) [Link] (1 responses)

What does NR_CPUS == 0 mean?

Optimizing for one CPU

Posted Jun 11, 2025 2:24 UTC (Wed) by iabervon (subscriber, #722) [Link]

I was thinking of NR_CPUS == 1, and I was thinking that the reason this wasn't supported was that cpuids were put in a field that is log(NR_CPUS) bits, which doesn't work in C because you can't have 0-bit fields. But it looks like it's actually fine to have NR_CPUS == 1 and should optimize pretty well, although the compiler probably won't figure out that any two cpuids are the same if NR_CPUS == 1.

Optimizing for one CPU

Posted Jun 11, 2025 10:49 UTC (Wed) by alx.manpages (subscriber, #145117) [Link] (7 responses)

We're talking in the C Committee about adding _BitInt(1) (C23 only supports _BitInt(2) and unsigned _BitInt(1), but not _BitInt(1)). Maybe it would be interesting to discuss adding support for 0 bits as well. I can forward this idea to the committee.

Optimizing for one CPU

Posted Jun 11, 2025 14:28 UTC (Wed) by willy (subscriber, #9762) [Link] (1 responses)

_BitInt(1) would support two values, 0 and -1? I can see the use, but also the confusion. I think there were similar problems with "signed int x:1;"

Optimizing for one CPU

Posted Jun 11, 2025 15:45 UTC (Wed) by alx.manpages (subscriber, #145117) [Link]

Yes, for consistency with 2's complement used elsewhere, the non-zero value in _BitInt(1) must be -1. Consensus seems to be forming that if we standardize it, it should be -1 and not 1.

Optimizing for one CPU

Posted Jun 14, 2025 15:02 UTC (Sat) by quotemstr (subscriber, #45331) [Link] (4 responses)

If you're going to do that, please also consider making void a vacuous value type instead of a special keyword. Simple and surprisingly powerful change. You'd be able to write, say, void x = foo(); bar(x).

Optimizing for one CPU

Posted Jun 14, 2025 17:25 UTC (Sat) by khim (subscriber, #9252) [Link] (3 responses)

> Simple and surprisingly powerful change.

Yes. Powerful enough to destroy countless programs.

You may take a look on Rust: it does gave zero sized types (and Rust's void is also zero-sized tuple). To make that work they had to include tons of checks everywhere.

Simply because now you, suddenly can take double your vector size as many times as you want without ever running out of memory. And do bazillion other similar things.

Plus clang/gcc have already adopted pointer arithmetic for void*, having actual zero-sized type would cause compatibility issues there, too.

Optimizing for one CPU

Posted Jun 14, 2025 18:03 UTC (Sat) by quotemstr (subscriber, #45331) [Link] (1 responses)

Yeah. You're right. The void* arithmetic thing settles it. It's a shame; the void as value C++ paper from a few years ago would have filed off a lot of metaprogramming edges.

Maybe it'd at least make sense to let _Generic work with void as an exception to the general rule against incomplete types?

Optimizing for one CPU

Posted Jun 14, 2025 18:15 UTC (Sat) by alx.manpages (subscriber, #145117) [Link]

_Generic already works with void in GCC 15:

alx@debian:~/tmp$ cat g.c
int
main(void)
{
return _Generic(void, void: 1);
}
alx@debian:~/tmp$ /opt/local/gnu/gcc/countof/bin/gcc -Wall -Wextra g.c
alx@debian:~/tmp$ ./a.out; echo $?
1

Optimizing for one CPU

Posted Jun 14, 2025 20:17 UTC (Sat) by iabervon (subscriber, #722) [Link]

You could just say that a 0-bit integer has enough padding to use up one whole address, so its size is 1. 1-bit integers have enough padding to have an integer size, and you could just say that any type that doesn't need any space for data at all still has to get to size(type) >= 1 by having padding. That would still allow for entirely optimizing out void local variables whose addresses aren't taken, and specifying ABIs such that void arguments are passed in registers without using any registers. And, actually, the clang/gcc pointer arithmetic for void* would make sense if each void item was enough padding to get a new address without any space used to store data.

Optimizing for one CPU

Posted Jun 14, 2025 17:20 UTC (Sat) by khim (subscriber, #9252) [Link]

C doesn't even have zero-sized type and that one is much more useful.

Unfortunately the assumption that any type have size of least one is used in bazillion places, thus it's hard to change that.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds