4 ms·
You could argue that it is a fault of the C language that it does not expose the carry flag of the CPU. This makes the most optimal implementation of e.g. addit
by mrich 13y ago
You could argue that it is a fault of the C language that it does not expose the carry flag of the CPU. This makes the most optimal implementation of e.g. addition impossible without resorting to (inline) assembler.
Of course not every CPU has a carry flag...
- artificialidiot 13y agoTBH, I have yet to see one which lacks CF.
- Tuna-Fish 13y agoOut of the top of my head, mips, Alpha, AM29000. There are plenty more.
- sp332 13y agoHead? you mean wikipedia? :) From https://en.wikipedia.org/wiki/Status_register#CPU_architectures_without_arithmetic_flags https://en.wikipedia.org/wiki/Status_register#CPU_architectu... those architectures put the carry result in a general-purpose register, but you still can't access the result in C.
- Tuna-Fish 13y agoThey were the three architectures that immediately sprung to mind when I though of cpus without carry bits. I have only programmed in assembly for two of them -- I might well have read that wiki page before.
- simias 13y agoExcept that exposing too much hardware state to the coder might give less room for the compiler to optimize aggressively for all architectures. What if the architecture doesn't have a carry? Then the compiler has to generate one when needed. What if the architecture has better ways to do the addition anyway? What if the architecture is only 8bit and even regular "int" adds take several instructions anyway, so it makes so sense opmimizing for 128bit adds? C doesn't even mandate what happens in case of an integer overflow, it has no business exposing carry flags. If I ever write a C tutorial I'll title it "How I learned to stop worrying and love the compiler". EDIT: of course in this case you can't really "let the compiler handle it" if you care about bignum performances. The only solution here would be a/ expose much more hardware state to the language, which as I've already stated doesn't sound very convenient or C-ish enough for me, b/ modify the optimizer to better handle bignum code or c/ use a bignum library and possibly make it part of the standard. I wouldn't be opposed to a standard <bignum.h>, I think it would make some sense. In the meantime I just use gmp.h, it's faster than anything I could come up with anyway, asm or otherwise. Bignum is hard.
- adr_ 13y agoUnsigned integer overflow is defined. I agree that the carry flag shouldn't be exposed directly, but the ability to express "add and check for overflow" would be useful and allow for these optimisations where the architecture supports it. Edit: But if you want to exploit the processor to its fullest, go with assembly. The compiler is good, but proving optimisations is a hard problem, and complex, single-instruction-specific optimisations aren't going to take off any time soon.
- zvrba 13y ago> What if the architecture doesn't have a carry? Then the compiler has to generate one when needed. Adding two N-bit numbers produces N+1-bit result, and C gives you no direct means of accessing the full result. IMO, this is a language defect and has little to do with HW support. [This pertains also to multiplication: NxN bits -> 2N-bit result.] If the hardware actually returns the full result, excellent; if no, the compiler has to synthesize code to compute it, if needed. Whether it's needed is inferrable by the code that follows, e.g., the type of the variable the result is assigned to. IMO, inferring that only a partial result is used (e.g., carry is discarded) is much easier for the optimizer than inferring what some instruction sequence is supposed to do. (E.g., 4+ multiplications and few additions => single 32x32=>64 multiply.)
- renox 13y ago> What if the architecture doesn't have a carry? Then the compiler has to generate one when needed. What is your point? If you want to do multiple precision arithmetic in assembly, then on the architectures which don't have a carry, you must indeed generate one, so what? If a language has some operations with carry, then it is up to the programmer to use them only when he needs them.. > C doesn't even mandate what happens in case of an integer overflow That's for performance reasons, and I would say that it is the wrong default aka 'premature optimisation', a better language would have 'int' with overflow checks (which could be disabled by a compiler switch) and int_raw for the unsafe&fast behaviour.
- sanxiyn 13y agoI note here that while C does not expose carry flag, LLVM does, and at least on x86 "with overflow" intrinsics do compile to the right instruction.