通过函数指针使用内在函数时的链接器错误
下面的代码不能使用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__))的此类方法的注释(
为clang),其他人(如Windows上的英特尔和cl,不要,可能做一些特别的事情。 static extern __inline __m128d __attribute __((__ gnu_inline__,__always_inline__,__artificial __))
))
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.