当通过函数指针使用内部函数时,链接器错误

Linker errors when using intrinsic function via function pointer

本文关键字:链接 错误 内部函数 函数 指针      更新时间:2023-10-16

下面的代码不能在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;

有些编译器,如gcc和clang,在这些方法上使用了一些特殊的注释(gcc为static extern __inline __m128d __attribute__((__gnu_inline__, __always_inline__, __artificial__)), clang为static __inline__ __attribute__((__always_inline__, __nodebug__))),而其他的(如Windows和cl上的Intel)则没有,而且可能在底层做了一些特殊的操作。

关键是这些函数不应该被认为是函数。它们不会显示任何序言,实现标准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,因此堆栈上的存储寄存器,很可能经历一些缓存丢失,等等。