On Jan 30, 8:46 pm, 88888 Dihedral <
dihedral88...@googlemail.com>
wrote:
For dealing with hardware there are two primary choices which are
preferred:
1. GPU: CUDA, OpenCL, OpenGL/GLSL, D3D/HLSL, Cg, etc.
2. CPU: SIMD/MT -JIT
The (1) is self-explatonary. The less often taken path is the (2),
which is very expensive to implement as in worst case it is task
comparable to writing optimizing compiler. In less complicated
scenario it is just putting macro blocks of machine code together in
controlled fashion. The middle ground is to generate the machine code
in intermediate format where all symbols are named and register
allocator is the largest single task to overcome.
In both cases the implementation language is not as interesting as
what is done with it. The (1) has the goal to create solid quality
microcode for the GPU to execute and have good paths for data to go
through. The (2) has the same idea, but instead of microcode we
generate code for the CPU ALU instead, the data paths are less
sensitive to latency but more sensitive to cache as this path is more
flexible than the streaming model preferred for GPU.
If you are writing inner loops in HLL like C/C++ in that case again,
the C does not offer any real-world advantage over C if the programmer
understands his tools and knows how the HLL constructs map into
hardware instructions. This requires some experience with the compiler
and linker toolchain to have realistic expectations of the outcome of
HLL expressions. Usually at this level two things are done:
1. The results are measured against other alternatives
2. The output assembly (.s, .asm) is inspected so that there aren't
any surprises like calls to _ftol, or call to inline method and so on.
Inline keyword cannot be trusted in generic portable code to always
get the job done, sure, macros and other constructs can be used to
guide the code into the right direction.
The main thing is to measure, profile and check the output and adjust
the source code accordingly. It is a realistic expectation that the
compilers get better over time, not worse, so any optimization along
these guidelines will stay effective. On the other hand, some work-
arounds to get better output become obsolete over time and more
straightforward and descriptive expression usually slowly gains
ground.
All code written with this mindset is CONTEMPORARY and gets STALE over
time! VERY important to keep in mind.
This kind of micro-optimization is unnecessary for most programmers
for most of the time. Especially now that we have hardware to process
streamed data. For example, seems that what you are working on is a 2D
matrix of input that you map into output with 2D, finite-size kernel..
this kind of workload is often ideal for graphics processor to take a
peek at. The problem with this kind of thinking is the round-trip to
GPU local address space and back, if you can't synchronize the data
processing w/o flushing you're better off using the CPU most of the
time, where the technique (2) comes in.
What I'm getting at in roundabout way is that the C vs. C++ argument
is out-dated and even if that is the language of choice for the actual
inner loop, the C++ doesn't have ANY disadvantage except poor
programmers. The C is more hard-core and has less facilities to fuck
things up if you don't know how everything works. IN THAT SENSE it is
much better choice rather than let some sloppy C++ programmer try to
do a good job w/ tool he has no idea how to use properly. The key
concept is that this same sloppy C++ programmer might be TOP GUN C
programmer, so let him use the tools he knows best. But this is
totally different argument than that the C++ is inherently slow; it's
not.