6

As I learn more about C and C++ I'm starting to wonder: How can a compiler use newer features of processors without limiting it just to people with, for example, Intel Core i7's?

Think about it: new processors come out every year with lots of new technologies. However you can't just only target them since a significant portion of the market will not upgrade to the latest and greatest processors for a long time.

I'm more or less wondering how this is handled in general by C and C++ devs and compilers. Do compilers make code similar to if SSE is supported, do this using it, else do that using the slower way or do developers have to implement their algorithm twice, or what?

More or less how do you release software that takes advantage of newer processor technologies while still keeping a low common denominator?

4
  • If anyone has a better title please edit, I had no idea what to put
    – TheLQ
    Mar 23, 2012 at 15:38
  • it depends on what flags you pass to your compiler what decisions it makes about generating code.
    – user7519
    Mar 23, 2012 at 15:44
  • 1
    Is my revised title better?
    – user28988
    Mar 23, 2012 at 15:51
  • 2
    Take a look at what Intel C++ compiler does... I was amazed myself when I had first seen it... en.wikipedia.org/wiki/Intel_C%2B%2B_Compiler This related to the third paragraph... :)
    – c0da
    Mar 23, 2012 at 15:52

3 Answers 3

2

Your best choice as a developer nowadays is to choose tools that are smart enough to take advantage of special instruction sets such as SSD and SIMD when they are available on the processor directly and, when they aren't, automatically fall back to software algorithms that emulate those features. The compiler manufacturer can tell you in their specifications whether or not they support this.

From the Wikipedia article for the Intel C++ Compiler:

The compiler or library can make multiple versions of a piece of code, each optimized for a certain processor and instruction set, for example SSE2, SSE3, etc. The system includes a function that detects which type of CPU it is running on and chooses the optimal code path for that CPU.

Amusingly, that algorithm seems to favor Intel processors.

GCC has a "march" optimization for compiling to a particular microprocessor architecture. The tradeoff is that some platform independence may be sacrificed. See http://www.linuxjournal.com/article/7269?page=0,1

LLVM doesn't appear to have processor-specific optimizations; this makes sense, because LLVM seeks to generate a machine-independent intermediate code representation, and then turns that machine-independent representation into executable machine code. So any code targeting a specific processor architecture would have to reside in that second step.

3
  • 1
    Just curious, do you know if GCC or Clang this? Also, does Intel's compiler do this with code not originally written with the SSE libraries?
    – TheLQ
    Mar 23, 2012 at 23:44
  • See my update.. Mar 24, 2012 at 5:19
  • The Intel processor dispatching / multiple architecture code generation stuff is indeed amazingly awesome (I'm not aware of anything equivalent in other mainstream compilers). If you're just writing "normal" code, you can leave it to the compiler to emit suitably vectorized versions using SSE. If you do want to provide your own asm/intrinsics versions, you can hook into the same runtime dispatching mechanisms yourself: software.intel.com/sites/products/documentation/studio/composer/…
    – timday
    Apr 7, 2012 at 8:40
2

"if SSE is supported, do this using it, else do that using the slower way": compilers could do this; e.g. x86 CPUs can report their capabilities via CPUID. Potentially, performing the check could slow down the code, so a compiler would have to ensure that the check is at least factored out of a loop, and perhaps do the check in advance and store the result in a variable (in case CPUID is slow). Another small problem is that the part of the unused version of the code will be brought into the cache (wasteful).

But MCVC does not do this; if you enable SSE2 it will emit SSE2 blindly, assuming the target processor supports it.

JIT compilers (.NET/Java) can easily support multiple architectures, since they only have to check the processor architecture once per function (or less) to decide how they will generate code. Obviously there's no need to generate multiple versions of the code in that case; the code can be tailored for the current CPU.

1

Agner Fogg's C++ Optimization Manual contains an extensive section (page 124: Section 13: "Making critical code in multiple versions for different instruction sets") on ways of dealing with this problem. (That document is one of a set.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.