9

我有一个使用 Yeppp 的应用程序!SIMD 库。该应用程序是用 C# 编写的。它在 Windows x86-32 和 x86-64 上完美运行。但是,当我在带有 Mono 的 Raspberry Pi 上运行应用程序时,出现以下异常(不确定是 ARM 问题、Mono 问题还是其他问题)。我试过以root身份运行只是为了检查,同样的例外。我注意到堆栈跟踪的“UnixLibraryLoader”部分,因此我确保 Yeppp DLL (Yeppp.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?)
4

3 回答 3

3

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

检测依赖于 SIGILL 处理只是使不受支持的指令被跳过。另一种可能性是未从资源中正确检索该库(或检索到错误的库,因为 Yeppp.Loader.LoadNativeLibrary 猜测将哪个本机库用于其运行的体系结构)并且在将执行传递给它时发生崩溃.

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

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

于 2015-06-18T18:15:21.477 回答
2

既然赏金已经结束,让我在这里把我的评论变成一个答案。

您使用的是预览版,因此它没有按您的预期工作可能不足为奇。


Raspberry Pi 1 没有 NEON 但有VFP2。尽管向量浮点的首字母缩写词具有误导性,但 VFP 指令不是 SIMD 指令(请参阅arm-cortex-a8-whats-the-difference-between-vfp-and-neonVFP SIMD 指令,如何?)。

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

使用 Yeppp 有什么好处!使用 Raspberry Pi 1 那么因为 VFP 指令不是 SIMD 指令?我的猜测是 GCC 没有很好地实现这些,因此使用 Yeppp! 明确地实现它可能是有利的。


我不确定他 Raspberry PI 1 的峰值失败率是多少。然而,基准已经衡量

  • 0.041 DP GFLOPS
  • 0.192 SP 浮点运算

Raspberry Pi 2 的 cortex A7 内核(具有 NEON 和 VFP3)可以执行以下操作:

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

Raspberry Pi 2 有四个内核,因此 PEAK 触发器是4* FLOPs/cycle/core.

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

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

但是,Raspberry PI 1 和 2 还有另一个 SIMD 选项。您可以在VideoCore IV上使用 Integer SIMD 指令(另请参阅NEON 指令集支持 SIMD)。你可以用这个实现定点。无论如何,这可能会给您带来比 NEON 更多的性能。

于 2015-06-19T09:29:10.280 回答
2

耶!支持两种 Linux ARM 平台:

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

大多数用于 Raspberry Pi 的 Linux 发行版都使用不寻常的ARMv6 + hard-floatABI。Yeppp! 的ARMv7-A + hard+float版本使用了树莓派不支持的 Thumb-2 指令。这就是为什么您SIGILL在尝试使用它时得到的原因。

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

  • 将 Raspberry Pi 与软浮点 Linux 发行版一起使用
  • 使用支持 ARMv7-A(以及 Thumb-2)的 Raspberry Pi 2
于 2015-06-26T13:44:20.947 回答