1
votes

I want to compile C code using GCC compiler for CPU that supports AVX instructions. But my build machine use Core Quad CPU which doesn't support AVX.

I read a lot of topics about cross compiling and didn't find the answer. Some specific details bellow.

C compiler from Intel can builds several microarch specific versions of functions in one binary. At runtime the one specific are chosen.

Compiling codes on different systems:

-xAVX -axCORE-AVX2

where -x gives the baseline for the compilation and -ax is a list of the feature-specific code paths to build. As the Intel compiler documentation explains:

If the compiler finds such an opportunity, it first checks whether generating a feature-specific version of a function is likely to result in a performance gain. If this is the case, the compiler generates both a feature-specific version of a function and a baseline version of the function. At run time, one of the versions is chosen to execute, depending on the Intel(R) processor in use. In this way, the program can benefit from performance gains on more advanced Intel processors, while still working properly on older processors and non-Intel processors. A non-Intel processor always executes the baseline code path.

Does it mean that C compiler from Intel put microarch specific instructions in one version of function and doesn't put these instructions in another version of function?

GCC compiler doesn't support multimicroarch support in this manner (excerption from upper link):

The GCC compilers do not support multiple code paths and so a "universally" optimized binary is not possible. Here -march gives the baseline and -mtune the processor to tune for whilst respecting the instruction set of the baseline

-march=corei7-avx -mtune=core-avx2

This means "using the features available to the SandyBridge processors tune the code so that it would run optimally on a Haswell processor". Such an optimization would not be able to make use of the FMA instructions as they are not present on the baseline.

This mean that GCC compiler doesn't put new instructions for target optimisation microarch. Isn't it?


So back to the task. For Intel compiler I can set base microarch as Core Quad (-x) and set optimisation for the recent microarch (-ax). It's should be work. I haven't tested it jet.

But how I can deal with GCC compiler? It doesn't put new instructions for target optimisation microarch (-mtune). If I set base microarch (-march), then configure provides next message:

configure: error: cannot run test program while cross compiling

Is it possible to solve this task with GCC compiler?

1
configure: error: cannot run test program while cross compiling — well, what do you expect? You shouldn't execute cross-compiled configure test programs on the host. You either execute them on the target (or an emulator), or not execute them at all. -march/-mcpu is the option you want (one of them is enough); don't bother with -mtune at least until you get it working.Vladislav Ivanishin
@phuclv Thank's for the info. I'll read it carefully.Yurij Goncharuk
@VladislavIvanishin I know that I can't run binaries for another microarch. So, I expect to get binary that compiled on the Core Quad CPU and contains AVX instructions. I'll not run compiled binary on the Core Quad CPU.Yurij Goncharuk
But this configure script is clearly trying to run those binaries, isn't it? That's what the error message says, anyway. Why the script is doning it is another question (seemingly it knows that you are cross-compiling). I'd recommend digging out the test from config.log and trying to understand what happened there.Vladislav Ivanishin

1 Answers

0
votes

The question wasn't clear. The question was mostly belong to configure script. When I pass --host=x86_64-pc-linux-gnu to configure script it enabled cross-compile mode and didn't run any AC_TRY_RUN instructions.

After successfully compilation I disassembled output binaries and found AVX instructions and registers.

So I'll consider that multiversion functions was introduced in GCC 4.8. It's appliances via __attribute__ preprocessor directive. Thanks to @phuclv for the info about GCC!