ARM website states that there are certain NEON optimized libraries and show examples of using them. Trying to incorporate them into an Android project that takes advantage of NEON architecture isn't possible. The header files and libraries aren't there.
Is there a way to manually import those into an Android project? I am particularly interested in OpenMAX.
If you know exactly what you need and you can't find it, its probably best just to go ahead and write your own assembly it may even out perform the library unless of course the library is written in pure assembly then that might be hard but any library written in C and assembly inline has room for some extra performance (although not an extreme amount).
Writing NEON codes is actually much easier than ARM codes.
Optimizing is a different story though......
It's just like the Holy Grail. Fully optimized NEON codes usually run 10~20 times faster than their counterparts written in C.
It's an extremely taxing job though.
Related
I have a pretty large project written in C++ for Windows, with some MSVC-specific fancy things, like __declspec(property), usage of SEH, extra template and macro flexibility, intrinsics and etc.
In a nutshell it consists of various applications and a shared library (lib), which is a pretty large "algorithmic" code. It's written entirely in plain C++ (MSVC's version of it, as I said), not dependent on any 3rd-party, all the code is "hand-made", no stdlib, STL, Boost or etc.
Now this code needs to be ported to mobile platforms, namely Android and iOS.
The code should be platform-independent. No explicit dependence on OS, besides the very basic things, like heap memory allocation. It does depend on some Windows-specific things: SEH, TLS, but those are the things I can sacrifice, if they can't be replaced.
And I'm thinking about how to deal with it. Cleaning the whole code from MSVC-specific stuff is possible, but not convenient. I'd prefer to keep them, and definitely I don't want to keep several codebases for different platforms.
So, what are the options at my disposal?
As I understood, there are C++ compilers for Android (part of NDK), but they are probably standard C++ compliant. Anyway, iOS development is based on Objective-C, which is a superset of plain C.
This led me to an idea to "compile" the existing MSVC-specific C++ code into a plain C. There is an option in MSVC compiler to generate "listing" files, containing the assembler code. I guess if there's an option to create appropriate listings containing C-code. Or alternatively MSVC-compliant 3rd party C++ -> C converters.
Any thoughts?
So, what are the options at my disposal?
Write portable C or C++ code.
I've got C and C++ libraries that run on Android, iOS, Windows Phone, Windows, BSD, OS X and Linux. The library is written once and it runs everywhere.
While the "core library" is portable C/C++, the next layer up is not. That's where the libraries integrate with the platform. For example, the iOS test suite driver has a Cocoa/CocoaTouch UI on Apple platforms, and an MFC test suite drive on Windows and Windows Mobile. And the test suite drivers on Linux are command line because I don't waste time with GTK or Qt.
The routines to seed the random number generators are platform specific. I consider them a core function, so its in the core library and guarded by platform specific #defines.
Don't make the mistake of re-implementing your core library on every platform it runs on. That means you will need 4x to 8x the development cycles to duplicate the code and behavior. And there will always be small, hidden behavioral bugs that you waste countless hours tracking down.
And I'm thinking about how to deal with it. Cleaning the whole code from MSVC-specific stuff is possible, but not convenient.
Yes, do this. Pay the tax once and enjoy the benefits for the remainder of the code's life.
This led me to an idea to "compile" the existing MSVC-specific C++ code into a plain C.
No, I would not do this. Remove the platform specific stuff from the core library. Make the core library portable.
MSVC++ to C compilers come in the "if you have to ask, you can't afford it" category. Just too small a market.
A more realistic chance would be to wait what Microsoft is doing. They're seriously looking into targeting additional mobile platforms with MSVC 2015.
TLS is probably the easiest, as that is standard C++ (thread_local). SEH should be mapped to regular C++ exception handling, which means you need to trap pointer bugs before they happen. MSVC isn't exactly known for extra template flexibility, it's in fact rather inflexible. x86 intrinsics obviously are right out on ARM.
I am embarking on some Android NATIVE coding (e.g. C++, not Java), and need to use the fairly undocumented sp<> ("Strong Pointer") refcount'd pointer class.
As far as I can tell, the Android sp<> template looks VERY much like the more familiar BOOST shared_ptr<> template. Standard refcount mechanism. They do NOT appear to be part-for-part compatible. For instance, Strong Pointers do NOT appear to be threadsafe. What other gotchas are there between the two?
A wider question would be: why is there no online reference for the NDK? Are they having enough diskspace problems on developer.android.com that they cannot fit it there? Grumble.
Android's sp<> is undocumented because it is part of the platform, and its implementation might change between platform revisions. You should not use it in NDK code, unless you copy all of the headers and corresponding source files into your own project.
It is intentionally not thread-safe for performance reason: actually doing thread-safe ref-counting requires adding memory barrier instructions which slow down the operation significantly on ARM (not so much on x86 and x86_64 though). Even Chrome uses two different classes to implement ref-counting for this reason (i.e. base::RefCounted and base::RefCountedThreadSafe).
As to other gotchas, I can't really tell, but I guess the implementation of weak pointers is also different from Boost. In all cases, if you don't understand what this code does, don't use it, it's not meant for general consumption.
I am just starting to learn OpenCV for Android, I have played around with it a bit and it all works fine.
I installed the NDK and managed to run some of the sample apps which included it.
I am not clear on what we need the NDK for. I could not find it referenced anywhere in the documentation.
Is there OpenCV functionality which is not available in the regular library 2.4.8 ?
Is it just so we can use modules written in c++ that others have made available, without rewriting them in java ?
I have been using NDK for my application and following are my
observations.
Yes, it gives the advantage of using plenty of c++
modules which are made available.
If you already have a bit of
experience in computer vision application programming using openCV
library in C++, you donĀ“t have to learn new syntaxes in java(can be quite
irritating some times).
Using NDK for your app can give you a slight upperhand in terms of
performance when image processing you do is computationally
demanding (I am not quite sure about this because the openCV
library made available for Android is just a wrapper around the
same header files and stuff and should almost give the same performance as NDK. I have never really compared the
performance myself but have read in various blogs that NDK is faster).
One thing
you really have to be careful when using NDK is calls from JAVA to
NDK side or the other way round, these calls can be really expensive in terms of performance(Needs careful planning).
Passing few parameters like array of MAT from JAVA to NDK are a bit
of headache, but you can find few workarounds.
Based on these and other factors you might have found out from various sources and also by your programming strengths you can decide if you want to use NDK or not. There was never really a set of guidelines i could find that says you can use NDK if so and so conditions are satisfied, people just start with which ever programming style they are more comfortable with.
In Android documentation they advice to use NDK in case of
# CPU-intensive operations that don't allocate much memory,
# such as signal processing, physics simulation, and so on.
If everything you want to do can be computed with OpenCV built'in functions, you may not need NDK as processing routines of OpenCV are already in C/C++.
However, if you have to process the images matrix intensively (I mean direct access to pixels), you will improve performances using the NDK.
I recently know that we can use Android NDK (use C++ language) to program. But, I'm afraid that, can we use Android NDK to do most of work in Android ? (because people just say that NDK just helps increasing performance of an android program)
I see that ADT plugin for eclipse is powerful, but It's for java. So, if I want to develop on Android NDK, does it has a plugin same with that.
thanks :)
Java is well-supported on Android: there are books, tutorials, Google results and a lot of similar documentation and resources. Developing with the NDK has less stuff available.
Although you can in principle write your full application in C++ using the NativeActivity, I believe that you will have less resources at your disposal for that, compared to Java. If you really want to make your Java program faster, you should profile it, to find which part needs this performance gain and write only that part in C++ using JNI.
you could, but it is not recommend. For one c++ and java performance for multiple aspects are equivalent, then every jni call has its overhead that you have to take in account. Take a look to this link
I believe I read at some point that due to Android running on the Dalvik VM, that dynamic languages for the JVM (Clojure, Jython, JRuby etc.) would be hard pressed to obtain good performance on Dalvik (and hence on Android). If I recall correctly, the reasoning was that under the hood, in order to achieve the dynamic typing, there was quite a bit of fiddling done with the java bytecode and that the bytecode->dalvik translation wouldn't pick this up easily.
So should I avoid a dynamic JVM language if I want to develop for Android?
EDIT: I guess I should have provided a bit more context. I was considering using Clojure to develop apps for Android. I was thinking about using Clojure for a few reasons:
I want to learn FP
I don't really care to learn Java
Clojure seems to have some very
interesting language concepts (STM
for example).
However, when I tried to write apps for Android in Clojure, I found that there is a performance issue that is unacceptable. But I found a blog posting that said that dynamically typed languages (Clojure for example) would have problems due to the bytecode manipulation needed to get the dynamic typing. So I was sort of looking for independent confirmation that this is true or it isn't. I should have known better than to make the assumption that in this particular issue all dynamically typed JVM languages could be treated as the same. I guess I did ask a fairly broad question so I guess I shouldn't be surprised that people didn't quite understand what I was asking.
Dan Bornstein gave a presentation on Dalvik at Google I/O. It's worth watching to learn about the system in general, including the constraints you care about. The specific issue of non-Java languages compiled into Java bytecode comes up during the Q&A.
Remco van 't Veer has a github project where he's patched Clojure to work on Android. Tim Riddell has written a tutorial on how to use it.
As mentioned here by #sean, there is sometimes a bigger problem than just performance. Dan Bornstein discusses it when asked about Jython, at ~54:00 in video. There is currently no support for dynamic languages which generate bytecode on-the-fly, (because the bytecode translation is not available at runtime).
Android just got scripting
There are some patches to make clojure work.
http://riddell.us/tutorial/clojure_android/clojure_android.html
I think the real issue is the use of byte code generators by some dynamic languages; they won't generate byte code for the Davlik VM. Therefore eval will not work.
Given the relatively speaking cramped hardware of the phone running you probably should just target java and not worry about a dynamic jvm language. They dynamic languages on the jvm aren't going to be as efficient as the java to my understanding.
Besides the Android SDK is pretty sane and easy to write for I don't think you'll experience very many benefits using something else.
dynamic languages for the JVM would be hard pressed to obtain good performance on Dalvik
Dynamic languages are hard pressed to obtain good performance, period. If you want performance, use a statically typed language like Java (or C#, F# etc.).