Counterpart of __assume in GCC
By chys on July 24th, 2010Microsoft Visual C++ has a keyword __assume, which is used to pass a hint to the compiler for optimization. It can be useful when optimizing hotspots in a program. For example, if we know a loop will run at least once, we can add an __assume hint:
__assume (0 < n);
for (i=0; i < n; i++)
/* .... */
This eliminates the comparison of n against zero before entering the loop body for the first time, without changing it to a do-while structure, which is usually less preferable than a for loop. Another typical use is to tell the compiler the default branch of a switch-case statement is unreachable.
GCC does not have a counterpart. But now that GCC 4.5.0 introduced __builtin_unreachable, we can do everything in GCC what we do with __assume in MSVC. My tests show the following macro works:
#define __assume(cond) do { if (!(cond)) __builtin_unreachable(); } while (0)
(The “do { ... } while (0)” statement is just a small trick in defining macros. Actually it’s been so well known and widely used that it can hardly be called a trick anymore.)
Switch from syslog-ng to rsyslog
By chys on July 16th, 2010I just think it is funny for a package as fundamental as system logger to depend on glib (part of the GTK+ project). (Of course, I don’t mean glib is a bad library. I’m not implying anything like that.)
Of course there are other reasons, but they are less important:
- Many distributions also prefer rsyslog to syslog-ng because it’s more powerful and scalable. [1] [2]
- Several people complained against the performance of syslog-ng [3], although the performance of syslog is normally not an issue for individual users.
- Third, I don’t understand why the author of syslog-ng prefers listening on
/dev/logas a stream socket (local counterpart of TCP) instead of a datagram one (local counterpart of UDP). (I know it can be changed in the configuration file.) None of the common issues of UDP is present in local datagram sockets: too short length limit; out of order; unreliability. On the contrary, syslog needs unidirectional channels carrying boundary-maintained messages, for which nothing can be more suitable. - Finally, licensing issues, upstream responsiveness, etc. They are less important for individual users, though.
Sure, syslog-ng also has its advantages. For example, I like the format of its configuration files.
GCC itself will use C++
By chys on June 1st, 2010It’s been announced on their mailing list that a subset of C++ will be allowed in the implementation of GCC itself.
In general, I think they’re doing the right thing. The only concern I have is, by doing so, whether they’re making bootstrapping or porting more complicated, which I will probably be doing frequently. Are they still going to allow bootstrapping on a system with only a C compiler, or are they assuming a C++ compiler is nowadays as fundamental as a C compiler?
Tags: GCC
const in C and C++
By chys on May 31st, 2010
The const keyword has “constant” and “read-only variable” semantics in C++, but only “read-only variable” semantics in C.
To illustrate this difference, try compiling the following code:
const int x = 2; int y[x];
This is not legal C, because x is not a compile-time constant semantically.
But it is legal C++, because const also has constant semantics and thus x is a compile-time constant.
Tags: C/C++
CPU Frequency Governor
By chys on May 21st, 2010Kernel documentation recommends “conservative” for laptops, citing latency reasons.
However, Intel explicitly recommends “ondemand” in its powertop. So does at least one Intel kernel developer.
OK. I have been using “conservative.” I decide to switch to “ondemand” from now on.
bc quit
By chys on May 19th, 2010Happened to see this in fortune:
quit When the quit statement is read, the bc processor
is terminated, regardless of where the quit state-
ment is found. For example, "if (0 == 1) quit"
will cause bc to terminate.
-- seen in the manpage for "bc". Note the "if" statement's logic.
Then I checked the man page of bc. It really says that.
NPTL_KERN_VER
By chys on May 3rd, 2010
In Gentoo, this variable can be used to specify the lowest kernel version we want glibc to support. For example, I am completely certain I will never use a kernel older than 2.6.30 on my Gentoo box, so I may want to add NPTL_KERN_VER="2.6.30" to /etc/make.conf. This way, glibc will assume the kernel supports all features that 2.6.30 supports and remove fallback codes written for old kernels.
The default value for NPTL_KERN_VER has been 2.6.9 for years.
That will not make a real difference, though. By switching from 2.6.9 to 2.6.30, the size of my /lib/libc.so.6 reduced by approximately 20KiB, or 1.3%.
Tags: Gentoo
NULL can be a valid address
By chys on April 21st, 2010It is only a convention to consider NULL (0) as an invalid pointer. Technically, the operating system or hardware does not really care if a pointer is zero or not, although operating systems may restrict the use of valid null pointers as they may be a security hole.
Consider this program:
#include <stdio.h>
#include <sys/mman.h>
int main ()
{
int *p = mmap (0, 4096, PROT_READ|PROT_WRITE,
MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
*p = 2554;
printf ("p=%p; *p=%d\n", p, *p);
return 0;
}
It attempts to make NULL (0) a valid address and then write to it. On Linux, it runs without error as root, but crashes as a normal user.
Note: Calling mmap with NULL as its first argument usually means the kernel will choose an address. However, if MAP_FIXED is also specified, it instead instructs the kernel to use the very address 0. Only privileged processes are allowed to do so; a non-privileged process only gets EPERM (Permission denied).
This also explains why MAP_FAILED is equal to (void *)-1 instead of NULL.
What exactly “-march=native” means
By chys on April 12th, 2010
GCC 4.2 introduced “-march=native”. With this option, GCC automatically optimizes for local computer.
I used to think GCC would simply replace it with an appropriate “-march=....” based on results of CPUID, so, for example, it would be equivalent to “-march=core2” on a Core 2 CPU.
Actually GCC does more than I guessed. We can observe what GCC actually replaces it with:
- Run
gcc -march=native -c -o /dev/null -x c -in one terminal;
- Open another terminal and type
ps af | grep cc1Then we will see how carefully GCC detects our CPU.
I tried this using GCC 4.4.1 on a computer equipped with a Core i3 CPU, and it turns out “-march=native” means
-march=core2 -mcx16 -msahf -mpopcnt -msse4.2 --param l1-cache-size=32 --param l1-cache-line-size=64 --param l2-cache-size=256 -mtune=core2
on this computer. It says:
- We can use SSE4.2 instructions,
CMPXCHG16B,SAHF/LAHF(in 64-bit mode),POPCNT, in addition to all instructions available on a Core 2; - The size of L1 and L2 caches are 32KiB and 256KiB, respectively; each L1 cache line is 64 bytes;
- Use instructions that are most suitable for Core 2 (Sure Core i3 is different from Core 2, but it is too new to have specific optimization support in compilers).
So, the conclusion: always use “-march=native” when compiling codes for local use.
Tags: GCC
Removed some distribution-specific patches
By chys on March 24th, 2010With all due respect to Gentoo developers, I really hate the patches they made for coreutils, especially the one to have uname parse /proc/cpuinfo.
The result is that uname -a displays more info, specifically the mode of the CPU, on Gentoo than other Linux distributions. Generally this is not a bad thing. But I do have concerns:
(1) In my view the utility uname should remain a simple wrapper of the homonym system call. If CPU/vendor info really needs to be returned by uname, it is better to add it to kernel. This is also part of the reason why upstream rejected this patch.
(2) If I am used to finding CPU info from uname, I will likely forget the more orthodox method (cat /proc/cpuinfo). A job interviewer may not be that patient to listen to my explanation about the patch.
