Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
150 views
in Technique[技术] by (71.8m points)

c++ - What is the need to generate ASM code in gcc, g++

To narrow down my question, let me describe my assumption and the experiment that I did...

My assumption: A code written in assembly language will run much faster than its C/C++ counterpart and also the executable size to be much smaller than that generated from C/C++ code.

The experiment: I wrote the below program in to bin2dec.c

#include <stdio.h>

int main()
{
    long int binary, decimal, reminder, exp;
    int i, j;

    for(i=0; i<10000; i++)
    {
        for(j=0; j<1000; j++)
        {
            binary = 11000101;

            exp = 1;
            decimal = 0;

            while(binary != 0)
            {
                reminder = binary % 10;
                binary = binary / 10;
                decimal = decimal + reminder * exp;
                exp *= 2;
            }   
        }
    }
    return 0;
}

Then generated the ASM code for it gcc -S bin2dec.c -o bin2dec.s

After that I compiled both the files as below

gcc bin2dec.c -o bin2dec_c
gcc bin2dec.s -o bin2dec_s

Test 1: Found out some internal details of both the files

[guest@localhost ASM]$ size bin2dec_c bin2dec_s
   text    data     bss     dec     hex filename
    951     252       4    1207     4b7 bin2dec_c
    951     252       4    1207     4b7 bin2dec_s

Result: Both are exactly same...

Test 2: Executed the files and calculated the time taken

[guest@localhost ASM]$ time ./bin2dec_c
real    0m1.724s
user    0m1.675s
sys     0m0.002s

[guest@localhost ASM]$ time ./bin2dec_s
real    0m1.721s
user    0m1.676s
sys     0m0.001s

Result: Both are same. Some time the executable generated from ASM ran slower :-(

So the question is, whether my assumptions were wrong? If not, what mistake I did so that both the executables bin2dec_c and bin2dec_s ran at the same speed? Is there any better way to get ASM code from a C/C++ program or I should rewrite all the logic from the scratch in ASM to gain the advantage of speed and program size?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It is an old tradition (in the 1970s on early Unix systems, the machine was so small that it was simpler to generate some assembler file), and some compilers can generate directly object files or machine code; probably some recent version of Clang/LLVM, or TinyCC (for C only: fast compilation time, but very slow executable!) perhaps some proprietary XLC compiler from IBM, and some people amongst the GCC community are thinking about that (notably for GCCJIT).

However, generating an assembler file is often easier for compiler developers. And since most of the compiler work happens in optimization passes (which are transforming some internal representations in the compiler), losing a few milliseconds to start the assembler is not very important.

With GCC, compile with gcc -time and gcc -ftime-report (and of course your usual optimization flags, e.g. -O2) to understand where the compiler spends its time. It is never in the assembler...

You might sometimes find useful to look into the generated assembler file. Compile your foo.cc C++11 file with g++ -O2 -Wall -S -fverbose-asm -std=c++11 foo.cc then look (with some editor or pager) into the generated foo.s assembler file.

You could even compile with g++ -fdump-tree-all -O2 and get hundreds of compiler dump files from GCC explaining what transformations the compiler did on your code.

BTW today's (superscalar, pipelined) processors (the ones in your desktop, your laptop, your tablet, your server) are so complex that in practice a compiler can optimize better than a human programmer. So practically speaking the assembler code produced by an optimizing compiler from some realistically sized C code (e.g. a C source file of a few hundred lines) is often faster than what an experimented assembler human programmer can code in a few weeks (less than a thousand assembler lines). In other words your assumption (that code human-written in assembler is faster/better than code human-written in C and compiled by a good optimizing compiler) is wrong in practice.

(BTW, an optimizing compiler is permitted to transform your bin2dec.c program, which has no observable side-effects, e.g. no input and output, into an empty program, and GCC 5.2 does that with gcc -O2 !!)

Read also about the halting problem and Rice's theorem. There is a intrinsic limitation in what optimizing compilers or static program analyzers can achieve.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...