在树莓派上使用Mono运行Yeppp库



我有一个应用程序使用Yeppp!SIMD图书馆。该应用程序是用c#编写的。它可以在Windows x86-32和x86-64上完美运行。然而,当我在带有Mono的树莓派上运行应用程序时,我得到以下异常(不确定这是ARM问题,Mono问题还是其他问题)。我试过以root身份运行只是为了检查,也有同样的异常。我注意到堆栈跟踪的"UnixLibraryLoader"部分,因此我确保Yeppp DLL (yepp . clr . bundle . DLL)与可执行文件位于同一目录中。这是我的代码的问题,我编译它的方式,还是与库的问题?

    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 sem_wait@@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 sem_wait@@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?)

我猜在RasPi的ARMV6硬浮动架构上的Mono,可能在处理Yepp (https://bitbucket.org/MDukhan/yeppp/src/40148ba4cdd00b03dfa880f6b7cecce83979c9d3/library/sources/library/Probe.arm.asm?at=default)中特征检测代码发出的故意SIGILL时遇到了麻烦,并且可能正在崩溃。

检测依赖于SIGILL处理,只使不支持的指令被跳过。另一种可能性是库没有正确地从资源中检索(或者在yeppp . loader . loadnativellibrary猜测为其运行的体系结构使用哪个本机库时检索到错误的库),并且当将执行传递给它时,事情会崩溃。

我同意你应该联系开发人员,因为我在网站上找不到任何参考资料,并且在我仔细阅读的源文件中表明支持RasPi及其旧版本的ARM。

p。:我假设您使用的是使用HardFloat的Raspbian,以及最近版本的Mono(最初使用不兼容的SoftFloat)。

耶!支持两种Linux ARM平台:

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

大多数树莓派的Linux发行版使用不寻常的ARMv6 + hard-float ABI。Yeppp !ARMv7-A + hard+float版本使用Thumb-2指令,这是树莓派不支持的。这就是为什么你得到SIGILL时,试图使用它。

我可以建议两种解决方法:

  • 使用树莓派与软浮动Linux发行版
  • 使用树莓派2,它支持ARMv7-A(因此大拇指-2)

现在赏金结束了,让我把我的评论放在这里的答案。

你正在使用预览版,所以它没有像你期望的那样工作可能并不奇怪。


树莓派1没有NEON,但有VFP2。VFP指令不是SIMD指令,尽管Vector Floating - Point的首字母缩略词具有误导性(参见arm-cortex-a8- VFP -and-neon和VFP SIMD指令之间有什么区别,如何?)。

VFPv2是在ARMv5TE、ARMv5TEJ和ARMv6架构中引入的。所以即使Yeppp!没有明确引用ARMV6并不一定意味着它不支持VFPv2,因为它引用了ARMV5T。

使用Yeppp的优势是什么?与树莓派1那么,因为VFP指令不是SIMD指令?我的猜测是GCC没有很好地实现这些,因此使用Yeppp!来显式地实现这些可能是有利的。


我不确定Raspberry PI 1的峰值是多少。然而,

  • 0.041 dp gflops
  • 0.192 sp gflops

树莓派2的cortex A7内核,具有NEON和VFP3,可以做:

  • 0.5 DP FLOPs/cycle:标量VMLA。F64每4个周期。
  • 1.0 DP FLOPs/cycle:标量VADD。
  • 2.0 SP FLOPs/cycle:标量VMLA。F32每周期。
  • 2.0 SP FLOPs/cycle: 2 wide VMLA。F32每隔一个周期。

树莓派2有四个内核,所以峰值是4* FLOPs/cycle/core.

请注意,使用Cortex-A7的Neon的峰值FLOPS与VFP的峰值FLOPS相同。Cortex-A7是100%与Cortex-A15兼容的二进制指令集,这就是为什么它被用于ARM处理器。小的设计。因此,Neon在Cortex-A7中实现只是为了兼容。

我还不知道每周期的整数运算。

然而,对于Raspberry PI 1和2,还有另一个SIMD选项。您可以在VideoCore IV上使用整数SIMD指令(参见NEON指令集支持SIMD)。你可以用这个来实现不动点。

最新更新