Significantly slower code when compiling with G++ instead of LLVM - c++

I am experimenting with an algorithm I programmed in C++ using XCode 7.0. When I compare the performance of the standard LLVM compiler in XCode to the binary created when compiling using G++ (5.2.0) the binary created using LLVM is an order of magnitude (>10x) faster than the code created using the g++ compiler.
I am using the -o3 code optimisation flag for the g++ compiler as follows:
/usr/local/Cellar/gcc/5.2.0/bin/g++-5 -o3 -fopenmp -DNDEBUG main.cpp \
PattersonInstance.cpp \
... \
-o RROTprog
The g++ compilation is needed because the algorithm has to be compiled and run on a high performance computer where I cannot use the LLVM compiler. Plus I would like to use Open MP to make the code faster.
All ideas on the reason what is causing these speed differences and how they could be resolved is more than welcome.
Thanks in advance for the help!
L

I can bet that what happens is the following: you pass -o3 to the compiler, instead of -O3 (i.e. with CAPITAL O) and for this reason -o3 just instructs the compiler to output the executable to a file called "3". However you use -o RROTprog later in the same command line, and the last -o is the one that's considered by the compiler when outputting the executable.
The net effect: the -O3 is not present, hence no optimization is being done.

Related

Should compiling c++ in Xubuntu 19.04 be different then compiling c++ in Ubuntu 18.04

Will there ever be a case where C++ code compiles with no errors in Ubuntu 18.04 and not compile in Xubuntu 19.04. My original guess was no but then a professor told me about there being some linker issues that may cause that. Also let me also add that the code is compiled using the same std and using g++.
Will there ever be a case where C++ code compiles with no errors in Ubuntu 18.04 and not compile in Xubuntu 19.04.
Possibly, but it only arises in corner cases. Most C++ code won't be affected.
I think it depends on GCC version. Around that time GCC started enabling PIE by default, and it caused some linking issues. See, for example, Initial SUPERCOP Haswell results for round 2. From the mailing list message:
... The rest of this message explains the -fPIC -fPIE above. On
exactly the same long-term-support version of Ubuntu, with the
supposedly compatible system-provided versions of gcc and clang, if
you run
gcc -c x.c; clang -c y.c; gcc -o x x.o y.o
where x.c says
#include <stdio.h>
extern int thenumber(void);
int main() { printf("%d\n",thenumber()); return 0; }
and y.c says
static int myconstant = 5;
int thenumber(void) { return myconstant; }
then compilation fails, while doing
gcc -c x.c; clang -c y.c; clang -o x x.o y.o
or
gcc -c x.c; gcc -c y.c; gcc -o x x.o y.o
or
clang -c x.c; clang -c y.c; clang -o x x.o y.o
works fine. The underlying problem is compiler-writer mismanagement of
an ongoing transition to
-fPIC: compiling libraries as "position-independent code" (this is typically advertised as being important for shared libraries);
-fPIE: compiling main() etc. as position-independent code (this is typically advertised as being important for the claimed security
benefits of address-space layout randomization); and
-pie: linking position-independent executables.
Code that's compiled as position-independent code can be linked into
position-dependent executables or position-independent executables. A
correctly managed transition would have consisted of
turning on -fPIC and -fPIE by default,
issuing automatic warnings for any position-dependent code,
waiting a specified number of years for people to get rid of any previously compiled position-dependent code, and finally
turning on -pie by default.
What happened instead was gcc suddenly turning on -pie, clumsily
breaking all existing position-dependent code and even managing to
break compatibility with clang on the same system---clang still
produces position-dependent code, and then gcc fails to produce an
executable. This is also why gcc now breaks
crypto_kem/ntruhrss701/avx2.

Why does gcc produce a different result when bulding from source compared to linking a static library?

I have a single C++14 file, my.cpp, and from within it I'm trying to use a C99 library called open62541. For the latter, both full source open62541.c/.h and a library libopen62541.a exist. In my.cpp, where I include the open62541.h, I'm using C++ specific code (e.g. iostream), so technically I'm mixing C and C++.
I can get my.cpp to compile successfully by referencing the libopen62541.a:
gcc -x c++ -std=c++14 -Wall my.cpp -l:libopen62541.a -lstdc++ -o out
This outputs no warnings, and creates an executable out.
However, if I try to compile using source code only:
gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -o out
I get a lot of ISO C++ warnings (e.g. "ISO C++ forbids converting a string constant to ‘char'*") and some "jump to label" errors originating from within open62541.c, resulting in compilation failure.
I can get compilation to succeed by using the -fpermissive switch:
gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -fpermissive -o out
which still outputs a lot of warnings, but creates the executable successfully. However, I'm unsure if doing this is a good idea.
Perhaps worth mentioning is that open62541.h considers C++ at the beginning:
#ifdef __cplusplus
extern "C" {
#endif
Given that .a library, which comes bundled with the open62541 library code, is supposedly built from the same source, why are the first two approaches not consistent in terms of warnings and errors generated? Why does one work and the other doesn't?
Should one method - linking .a vs referring to .c - be preferred to another? I was under impression that they should be equivalent, but apparently they aren't.
Is using -fpermissive in this case more of a hack that could mask potential problems, and should thus be avoided?
The error (and warning) you see are compilation errors (and warning) output by a C++ compiler when compiling C code.
For instance, in C "literal" has type char[] while in C++ it has type const char[].
Would you get a C++ compiler build libopen62541.a from open62541.c, you would see the same errors (warnings). But a C compiler might be OK with it (depending on the state of that C source file).
On the other hand, when you compile my.cpp and links it against libopen62541.a, the compiler doesn't see that offending C code, so no errors (warnings).
From here, you basically have two options:
Use the procompiled library if it suits you as is
g++ -std=c++14 -Wall -Wextra -Werror my.cpp -lopen62541.a -o out
Compile the library's code as a first step if you need to modify it
gcc -Wall -Wextra -Werror -c open62541.c
g++ -std=c++14 -Wall -Wextra -Werror -c my.cpp
g++ open62541.o my.o -o out
gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -o out
This command forces the C code in open62541.c to be compiled as C++. That file apparently contains constructs that are valid in C but not C++.
What you should be doing is compiling each file as its own language and then linking them together:
gcc -std=gnu11 -Wall -c open62541.c
g++ -std=gnu++14 -Wall -c my.cpp
g++ -o out my.o open62541.o
Wrapping up those commands in an easily repeatable package is what Makefiles are for.
If you're wondering why I changed from the strict -std=c++14 to the loose -std=gnu++14 mode, it's because the strict mode is so strict that it may break the system headers! You don't need to deal with that on top of everything else. If you want a more practical additional amount of strictness, try adding -Wextra and -Wpedantic instead ... but be prepared for that to throw lots of warnings that don't actually indicate bugs, on the third-party code.

What is option -O3 for g++ and nvcc?

I'm new to nvcc and I've seen a library where compilation is done with option -O3, for g++ and nvcc.
CC=g++
CFLAGS=--std=c++11 -O3
NVCC=nvcc
NVCCFLAGS=--std=c++11 -arch sm_20 -O3
What is -O3 doing ?
It's optimization on level 3, basically a shortcut for
several other options related to speed optimization etc. (see link below).
I can't find any documentation on it.
... it is one of the best known options:
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
http://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/#options-for-altering-compiler-linker-behavior

what optimization passes are done for -O4 in clang?

We are trying to implement a jit compiler whose performance is supposed to be same as doing it with clang -o4. Is there a place where I could easily get the list of optimization passes invoked by clang with -o4 is specified?
As far as I know -O4 means same thing as -O3 + enabled LTO (Link Time Optimization).
See the folloing code fragments:
Tools.cpp // Manually translate -O to -O2 and -O4 to -O3;
Driver.cpp // Check for -O4.
Also see here:
You can produce bitcode files from clang using -emit-llvm or -flto, or the -O4 flag which is synonymous with -O3 -flto.
For optimizations used with -O3 flag see this PassManagerBuilder.cpp file (look for OptLevel variable - it will have value 3).
Note that as of LLVM version 5.1 -O4 no longer implies link time optimization. If you want that you need to pass -flto. See Xcode 5 Release Notes.

How to link libstdc++ statically with clang++

I'm trying to learn C++ deeper by reading source of STL as well as debugging it, so I want to link libstdc++ statically to my program, and it works fine using g++. However, how can I achieve the same thing with clang++ in llvm?
In another way, the question is, what is the clang++ equivalent of -static-libgcc?
Makefile I'm using
CXX=g++
CC=g++
LDFLAGS=-g -O0 -static-libgcc
CFLAGS=-O0 -Wall
CXXFLAGS=$(CFLAGS)
The flag you're looking for, in both GCC and Clang, is: -static-libstdc++