使用函数指针调用内置函数时出现链接错误

4
以下代码在Visual Studio 2013中无法编译。我收到了mm函数的链接器错误未解决外部符号(LNK 2019)。如果直接使用这些函数,则所有内容均可链接。 为什么不能编译?是否存在解决方法?
        #include "emmintrin.h"
        #include <smmintrin.h>
        #include <intrin.h>


        __m128i (*load)(const __m128i*) = NULL;

        if (it::isAligned<16>(ucpSrc, iXOffset * sizeof(unsigned char)) )
            load = &_mm_load_si128;
        else
            load = &_mm_lddqu_si128;

sizeof(unsigned char) 是 1。 - curiousguy
这些肯定是普通函数而不是函数对象类吧? - πάντα ῥεῖ
3
这些内置函数不是函数,而是由编译器插入的单个机器指令。 - Bo Persson
@user - 我会写两个循环,或者更好的方法是确保一切都对齐 - Bo Persson
1
如果你真的在问这个问题,我怀疑你可能不理解基本的x86汇编和/或低级编程。在现代处理器上,函数调用比未对齐的加载要糟糕得多。 - Mysticial
显示剩余2条评论
1个回答

2
一些编译器(如gcc和clang)在此类方法上使用一些特殊注释(对于gcc为static extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__)),对于clang为static __inline__ __attribute__((__always_inline__, __nodebug__))),而其他编译器(如Intel在Windows上和cl)则不需要并且可能在底层执行一些特殊操作。关键是这些函数不能被视为函数。它们不会显示任何前导信息,实现标准ABI。这只是调用某些汇编指令的C语法方式,比__asm (...)更易读。我相信您可以使用以下内容完成此函数指针操作:
__m128i load_aligned (const __m128i* p)
{
    return _mm_load_si128(p);
}

__m128i load_unaligned (const __m128i* p)
{
    return _mm_lddqu_si128(p);
}


__m128i (*load)(const __m128i*) = NULL;

void f(bool a)
{
    if (a)
        load = load_aligned;
    else
        load = load_unaligned;
}

int main()
{
    __m128i a, b ;
    f(argc != 0);
    return 0;
}

我想强调一下性能问题:使用函数指针比始终使用未对齐的加载要昂贵得多。当内存对齐时,未对齐的加载的开销大约为几个百分点,而调用函数指针将强制你遵守ABI,在堆栈上存储寄存器,很可能会经历几次缓存未命中等操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接