通过函数指针使用内在函数时的链接器错误

问题描述:

下面的代码不能使用visual studio 2013编译。我得到链接器 mm 函数的错误未解析的外部符号(LNK 2019)。如果我直接使用的功能,它所有的链接罚款。
为什么它不编译?

The code below doesn't compile with visual studio 2013. I get linker Error unresolved external symbol(LNK 2019) for the mm functions. If i use the functions directly, it all links fine. Why it doesn't compile? And is there a work-around

        #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;


如果gcc和clang等编译器使用一些特殊的对于gcc或静态__inline__ __attribute __((__ always_inline__,__nodebug__))的此类方法的注释( static extern __inline __m128d __attribute __((__ gnu_inline__,__always_inline__,__artificial __)) ))为clang),其他人(如Windows上的英特尔和cl,不要,可能做一些特别的事情。

Where some compilers such as gcc and clang use some special annotation on such methods (static extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__)) for gcc, or static __inline__ __attribute__((__always_inline__, __nodebug__)) for clang), others (like Intel on Windows and cl, don't and probably do something special under the hood.

事情是这些函数不是被认为是函数,他们不会显示任何前言,实现标准ABI。这些只是一个C语法的方式调用一些汇编指令,比 __ asm (...)

Key thing is that these functions are not meant to be considered as functions. They will not show any preamble, implement standard ABI. Those are just a C-syntax way to invoke some assembly instruction, more readable than a __asm (...)

我相信你可以用这个函数来完成这个函数指针:

I believe you can accomplish this function pointer thing with:

__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,因此存储寄存器在堆栈,很可能通过一些高速缓存未命中等。

I would highlight a performance note though: using a function pointer is going to be immensely more expensive than simply using the unaligned load all the time. The overhead of unaligned loads is about a few percents when memory is aligned where calling a function pointer will force you respect the ABI, hence store registers on the stack, most probably go through a few cache misses, etc.