【问题标题】:Porting to Mac OS X error移植到 Mac OS X 错误
【发布时间】:2016-02-29 08:37:15
【问题描述】:

我有跨平台的音频处理应用程序。它是使用 Qt 和 PortAudio 库编写的。我还将Chaotic-Daw 源用于一些音频处理功能(Vibarto 效果和软拐点动态范围压缩)。问题是我无法将我的应用程序从 Windows 移植到 Mac OSX,因为我收到了 __asm 部分的编译器错误(我使用 Mac OSX Yosemite 和 Qt Creator 3.4.1 IDE):

/用户/管理员/我的 项目/MySound/daw/basics/rosic_NumberManipulations.h:69:
错误: 预期在 'asm' 之后有 '(' { ^

对于这样的行:

INLINE int floorInt(double x)
{
    const float round_towards_m_i = -0.5f;
    int i;

    #ifndef LINUX
    __asm
    { // <========= error indicates that row
      fld x;
      fadd st, st (0);
      fadd round_towards_m_i;
      fistp i;
      sar i, 1;
    }
    #else
    i = (int) floor(x);
    #endif

    return (i);
}

我该如何解决这个问题?

【问题讨论】:

    标签: c++ macos clang cross-platform


    【解决方案1】:

    代码显然是为 Microsoft 的 Visual C++ 编译器编写的,因为这是它用于 inline assembly 的语法。它使用 Intel 语法并且相当简单,这使得它易于编写但阻碍了它的优化潜力。

    Clang 和 GCC 都使用不同的格式进行内联汇编。特别是,他们使用GNU AT&T syntax。写起来更复杂,但更具表现力。编译器错误基本上是 Clang 告诉你的方式,“我可以告诉你正在尝试编写内联汇编,但你的格式都错了!”

    因此,要编译此代码,您需要将 MSVC 样式的内联汇编转换为 GAS 格式的内联汇编。它可能看起来像这样:

    int floorInt(double x)
    {
        const float round_towards_m_i = -0.5f;
        int i;
    
        __asm__("fadd   %[x], %[x]  \n\t"
                "fadds  %[adj]      \n\t"
                "fistpl %[i]        \n\t"
                "sarl   $1, %[i]"
               : [i]   "=m" (i)    // store result in memory (as required by FISTP)
               : [x]   "t"  (x),   // load input onto top of x87 stack (equivalent to FLD)
                 [adj] "m"  (round_towards_m_i)
               : "st");
    
        return (i);
    }
    

    但是,由于 GAS 风格的额外表现力,我们可以将更多工作卸载到内置优化器,这可能会产生更优化的目标代码:

    int floorInt(double x)
    {
        const float round_towards_m_i = -0.5f;
        int i;
    
        x += x;                  // equivalent to the first FADD
        x += round_towards_m_i;  // equivalent to the second FADD
        __asm__("fistpl %[i]"
               : [i]   "=m" (i)
               : [x]   "t"  (x)
               : "st");
        return (i >> 1);         // equivalent to the final SAR
    }
    

    Live demonstration
    (请注意,从技术上讲,像最后一行所做的那样的有符号右移是在 C 中实现定义的,通常是不可取的。但是,如果您使用的是内联汇编,您已经决定针对特定平台,因此可以依赖特定于实现的行为.在这种情况下,我知道并且可以很容易地证明所有C编译器都会生成SAR指令来做算术正确-shift 有符号整数值。)

    也就是说,当您为LINUX 以外的平台(大概是 Windows,他们希望你使用微软的编译器)。因此,您只需确保在命令行或 makefile 中定义 LINUX,即可编译代码。

    我不确定为什么会做出这个决定; Clang 和 GCC 都将生成与 MSVC 相同的低效代码(假设您针对的是老一代 x86 处理器并且无法使用 SSE2 指令)。这取决于您:代码可以以任何一种方式运行,但如果不使用内联汇编来强制使用这种巧妙的优化,它会变慢。

    【讨论】:

      猜你喜欢
      • 2013-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-26
      • 2017-07-04
      • 2014-05-04
      • 1970-01-01
      相关资源
      最近更新 更多