2015-06-09 12 views
9

Ich habe eine Anwendung mit dem Yeppp! SIMD-Bibliothek. Die Anwendung wird in C# geschrieben. Es läuft perfekt auf Windows x86-32 und x86-64. Allerdings, wenn ich die Anwendung auf einem Raspberry Pi mit Mono ausführen, erhalte ich die folgende Ausnahme (nicht sicher, ob es ein ARM-Problem, ein Mono-Problem oder etwas anderes ist). Ich habe versucht, als root nur zu überprüfen, auch die gleiche Ausnahme. Ich bemerkte den "UnixLibraryLoader" -Teil des Stack-Trace, also stellte ich sicher, dass die Yeppp-DLL (Yeppp.CLR.Bundle.dll) im selben Verzeichnis wie die ausführbare Datei ist, was sie ist. Ist das ein Problem mit meinem Code, der Art, wie ich ihn kompiliert habe, oder einem Problem mit der Bibliothek?Ausführen von Yeppp-Bibliothek mit Mono auf Raspbery Pi

Stacktrace: 

    at <unknown> <0xffffffff> 
    at (wrapper managed-to-native) Yeppp.UnixLibraryLoader.dlopen (string,int) <0xffffffff> 
    at Yeppp.UnixLibraryLoader.Yeppp.INativeLibraryLoader.LoadLibrary (string) <0x0002f> 
    at Yeppp.NativeLibrary..ctor (string,Yeppp.INativeLibraryLoader) <0x0006b> 
    at Yeppp.Loader.LoadNativeLibrary() <0x000db> 
    at Yeppp.Library.Init() <0x00027> 
    at <Module>..cctor() <0x0000b> 
    at (wrapper runtime-invoke) object.runtime_invoke_void (object,intptr,intptr,intptr) <0xffffffff> 
    at <unknown> <0xffffffff> 
    at SimdSpeedTest.Program.DisplayCpuFeatures() <0x00033> 
    at SimdSpeedTest.Program.Main (string[]) <0x000c7> 
    at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <0xffffffff> 

Native stacktrace: 


Debug info from gdb: 

[Thread debugging using libthread_db enabled] 
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1". 
[New Thread 0xb5b7b430 (LWP 2272)] 
0xb6eabaac in waitpid() from /lib/arm-linux-gnueabihf/libpthread.so.0 
    Id Target Id   Frame 
    2 Thread 0xb5b7b430 (LWP 2272) "mono" 0xb6ea9770 in [email protected]@GLIBC_2.4() from /lib/arm-linux-gnueabihf/libpthread.so.0 
* 1 Thread 0xb6f80000 (LWP 2271) "mono" 0xb6eabaac in waitpid() from /lib/arm-linux-gnueabihf/libpthread.so.0 

Thread 2 (Thread 0xb5b7b430 (LWP 2272)): 
#0 0xb6ea9770 in [email protected]@GLIBC_2.4() from /lib/arm-linux-gnueabihf/libpthread.so.0 
#1 0x001fff10 in mono_sem_wait (sem=0x2f523c, alertable=1) at mono-semaphore.c:119 
#2 0x0017db28 in finalizer_thread (unused=<optimized out>) at gc.c:1073 
#3 0x001625b4 in start_wrapper_internal (data=0xb0d8c8) at threads.c:643 
#4 start_wrapper (data=0xb0d8c8) at threads.c:688 
#5 0x001f5c30 in thread_start_routine (args=0xac86c0) at wthreads.c:294 
#6 0x00204268 in inner_start_thread (arg=0xac86b4) at mono-threads-posix.c:49 
#7 0xb6ea2c00 in start_thread() from /lib/arm-linux-gnueabihf/libpthread.so.0 
#8 0xb6e0f728 in ??() from /lib/arm-linux-gnueabihf/libc.so.6 
#9 0xb6e0f728 in ??() from /lib/arm-linux-gnueabihf/libc.so.6 
Backtrace stopped: previous frame identical to this frame (corrupt stack?) 

Thread 1 (Thread 0xb6f80000 (LWP 2271)): 
#0 0xb6eabaac in waitpid() from /lib/arm-linux-gnueabihf/libpthread.so.0 
#1 0x000b2148 in mono_handle_native_sigsegv (signal=<optimized out>, ctx=<optimized out>) at mini-exceptions.c:2299 
#2 0x00027af8 in mono_sigsegv_signal_handler (_dummy=11, info=0xbe9280e0, context=0xbe928160) at mini.c:6777 
#3 <signal handler called> 
#4 0xb6f6d754 in ??() from /lib/ld-linux-armhf.so.3 
#5 0xbe9284a0 in ??() 
Cannot access memory at address 0x3000 
#6 0xbe9284a0 in ??() 
Cannot access memory at address 0x3000 
Backtrace stopped: previous frame identical to this frame (corrupt stack?) 
+0

unterstützt Cool, dass du Yeppp benutzt! ! –

+0

Ja, ich experimentiere schon eine Weile damit. Ich mag es wirklich, wie es für mehrere Sprachen und Betriebssysteme verfügbar ist. Ich kann es kaum erwarten, es dann mit parallel/async/concurrent/multi-threaded-Code etc. für noch mehr Leistung zu kombinieren. – user9993

+0

Ich starre jetzt mit Raspberry-Pi. Ich habe Intel intrinsics für SIMD benutzt, aber ich möchte meinen Code auf ARM jetzt, also brauche ich NEON. Yepp! scheint eine gute Wahl zu sein, also werde ich es wahrscheinlich bald ausprobieren. Ich kann dir nicht helfen, aber der Autor von Yeppp! ist auf SO und kann Ihre Frage beantworten. –

Antwort

3

Ich würde vermuten, Mono auf der ARMv6 Fest-Float-Architektur von Raspi, wahrscheinlich Schwierigkeiten hat die absichtliche SIGILL durch den Merkmalserkennungscode in Yepp ausgestellt im Umgang mit (https://bitbucket.org/MDukhan/yeppp/src/40148ba4cdd00b03dfa880f6b7cecce83979c9d3/library/sources/library/Probe.arm.asm?at=default) und kann kollabiert werden.

Die Erkennung hängt von der SIGILL-Behandlung ab, damit die nicht unterstützten Anweisungen übersprungen werden. Eine andere Möglichkeit ist, dass die lib nicht korrekt von der Ressource abgerufen wird (oder die falsche wird abgerufen, da die Yeppp.Loader.LoadNativeLibrary schätzt, welche native lib für die Architektur verwendet werden soll), und wenn die Ausführung an sie übergeben wird, stürzt die Bibliothek ab .

Ich zweitens sollten Sie den Entwickler kontaktieren, da ich keine Referenz in der Website finden konnte, und auf den Quelldateien, die ich durchgelesen habe, die anzeigen, dass RasPi und seine ältere Version von ARM unterstützt wird.

PS .: Ich nahm an, dass Sie Raspbian verwenden, das HardFloat verwendet, und eine neuere Version von Mono (die ursprünglich die inkompatible SoftFloat verwendete).

+1

Yeppp! auf seiner Homepage sagt ausdrücklich, dass es ARMv6 unterstützt "Yeppp! erkennt alle öffentlich angekündigten ARM-Befehlssätze, einschließlich ARMv6, ARMv7, VFPv3, VFPv4, NEON, NEONv2, halbpräzise Erweiterungen und Hardware Division Extension. Einige Erweiterungen können sogar erkannt werden Wenn der Linux-Kernel sie nicht kennt, sind die Yeppp! -Compute-Kernel für ARM Vector Floating-Point- (VFP) und NEON-Befehlssätze optimiert. " –

+0

Danke @Zboson für die Klärung. :) – Monoman

+0

Ihre Annahmen entpuppen sich als näher an der richtigen Antwort vom Entwickler als meine. –

2

Jetzt, da die Bounty vorbei ist, lass mich meine Kommentare in eine Antwort hier setzen.

Sie verwenden eine Vorschau, so dass es nicht überraschend ist, dass es nicht wie erwartet funktioniert.


Der Raspberry Pi 1 nicht über NEON aber tut VFP2. Die VFP-Anweisungen sind trotz der irreführenden Abkürzung von Vector Floating Point keine SIMD-Befehle (siehe arm-cortex-a8-whats-the-difference-between-vfp-and-neon und VFP SIMD Instructions, howto?).

VFPv2 wurde mit den Architekturen ARMv5TE, ARMv5TEJ und ARMv6 eingeführt. Auch wenn the source code for Yeppp! ARMV6 nicht explizit referenziert, bedeutet dies nicht unbedingt, dass es VFPv2 nicht unterstützt, da es ARMV5T referenziert.

Was wäre der Vorteil der Verwendung von Yeppp! mit dem Raspberry Pi 1 dann seit VFP Anweisungen sind nicht SIMD Anweisungen? Meine Vermutung ist, dass GCC diese nicht gut implementiert und daher kann es vorteilhaft sein, dies explizit mit Yeppp! Zu tun.


Ich bin mir nicht sicher, was die Peak-Flops von Raspberry PI 1 ist. However, benchmarks have measured

  • 0,041 DP Gflops
  • 0,192 SP GFLOPS

The cortex A7 cores, which which has NEON and VFP3, of the Raspberry Pi 2 can do:

  • 0,5 DP flops/Zyklus: skalare VMLA.F64 alle vier Zyklen.
  • 1.0 DP FLOPs/Zyklus: Skalar VADD.F64 in jedem Zyklus.
  • 2.0 SP FLOPs/Zyklus: Skalar VMLA.F32 in jedem Zyklus.
  • 2.0 SP FLOPs/Zyklus: 2-Wide VMLA.F32 jeden zweiten Zyklus.

Die Raspberry Pi 2 verfügt über vier Kerne, so dass die PEAK-Flop ist 4* FLOPs/cycle/core.

Beachten Sie, dass der Peak-FLOP von Neon mit dem Cortex-A7 ist das gleiche wie die Spitzen FLOP von VFP. Der Cortex-A7 ist ein zu 100% binärer Befehlssatz, der mit dem Cortex-A15 kompatibel ist, weshalb er im ARM big.LITTLE Design verwendet wird. Also ist Neon im Cortex-A7 implementiert, nur um kompatibel zu sein.

Ich weiß nicht über Integer Operationen pro Zyklus noch nicht.

Es gibt jedoch eine weitere SIMD-Option für den Raspberry PI 1 und 2. Sie können Integer SIMD-Anweisungen auf dem VideoCore IV verwenden (siehe auch NEON instruction set support SIMD). Sie könnten damit einen Fixpunkt implementieren. Dies könnte Ihnen möglicherweise viel mehr Leistung als NEON geben.

2

Yeppp! unterstützt zwei Linux ARM-Plattformen:

  • ARMv5TE + soft-float ABI (arm-linux-gnueabi)
  • ARMv7-A + hard-float ABI (arm-linux-gnueabihf)

meisten Linux-Distributionen für Raspberry Pi ARMv6 + hard-float ABI ungewöhnlich verwenden. Yeppp! 'S ARMv7-A + hard+float Version verwendet Thumb-2-Anweisungen, die nicht von Raspberry Pi unterstützt werden. Deshalb erhalten Sie SIGILL, wenn Sie versuchen, es zu verwenden.

I zwei Lösungen vorschlagen kann:

  • Verwenden Himbeere Pi mit Soft-float Linux Verteilung
  • Verwenden Himbeere Pi 2, die ARMv7-A (und somit Thumb-2)