哪些头文件为不同的x86 SIMD指令集扩展(MMX,SSE,AVX,...)提供内在函数?似乎不可能在网上找到这样的清单.如我错了请纠正我.
我目前正在编写一个树枚举器,我遇到了以下问题:
我正在查看屏蔽的位集,即位集,其中设置位是掩码的子集,即0000101使用掩码1010101.我想要完成的是增加位集,但仅限于屏蔽位.在这个例子中,结果将是0010000.为了使它更清晰一点,只提取掩码位,0011即将0100它们递增并再次分配给掩码位,给出0010000.
有没有人看到一种有效的方法来做到这一点,没有使用bitcans和前缀掩码的组合手动实现操作?
我参与了其中一个挑战,你试图生成尽可能小的二进制文件,所以我在没有 C或C++运行时库(RTL)的情况下构建我的程序.我没有链接到DLL版本或静态版本.我甚#include至没有头文件.我有这个工作正常.
有些RTL函数memset()可能很有用,所以我尝试添加自己的实现.它在Debug构建中工作正常(即使对于编译器生成隐式调用的那些地方memset()).但是在Release版本中,我得到一个错误,说我无法定义内部函数.您可以看到,在发布版本中,内部函数已启用,并且memset()是内在函数.
我希望memset()在我的发布版本中使用内在函数,因为它可能内联,比我的实现更小,更快.但我似乎是一个陷阱22.如果我没有定义memset(),链接器会抱怨它是未定义的.如果我确定它,编译器会抱怨我无法定义内部函数.
有没有人知道定义,声明,#pragma编译器和链接器标志的正确组合,以获得内部函数而不会拉入RTL开销?
Visual Studio 2008,x86,Windows XP +.
为了使问题更具体:
extern "C" void * __cdecl memset(void *, int, size_t);
#ifdef IMPLEMENT_MEMSET
void * __cdecl memset(void *pTarget, int value, size_t cbTarget) {
char *p = reinterpret_cast<char *>(pTarget);
while (cbTarget > 0) {
*p++ = static_cast<char>(value);
--cbTarget;
}
return pTarget;
}
#endif
struct MyStruct {
int foo[10];
int bar;
};
int main() …Run Code Online (Sandbox Code Playgroud) 这将是一个非常简单的问题(可能重复),但我无法找到它.
Win32 API提供了一组非常方便的原子操作(作为内在函数),例如InterlockedIncrement发出lock addx86代码.另外,InterlockedCompareExchange映射到lock cmpxchg.
但是,我想在Linux中用gcc做到这一点.由于我正在使用64位,因此无法使用内联汇编.是否存在gcc的内在函数?
ARM参考手册没有详细介绍各个指令(http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0348b/BABIIBBG.html).有没有更详细的东西?
我有一些代码,最初是由MSVC工作人员给我的,我正试图让它在Clang上工作.这是我遇到麻烦的功能:
float vectorGetByIndex( __m128 V, unsigned int i )
{
assert( i <= 3 );
return V.m128_f32[i];
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误如下:
Member reference has base type '__m128' is not a structure or union.
Run Code Online (Sandbox Code Playgroud)
我环顾四周,发现Clang(也许是GCC)在将__m128视为结构或联合时遇到了问题.但是我还没有找到一个直接的答案,我怎么能得到这些价值.我已经尝试过使用下标运算符而无法做到这一点,我已经浏览了大量的SSE内在函数列表并且尚未找到合适的函数.
我使用了很多SSE编译器内在函数编写了一个3D矢量类.一切正常,直到我开始实现具有3D矢量作为新成员的类.我在发布模式下经历了奇怪的崩溃,但在调试模式下却没有,反之亦然.
所以我读了一些文章,并认为我需要将拥有3D矢量类实例的类对齐到16个字节.所以我只是在类之前添加了_MM_ALIGN16(__declspec(align(16)),如下所示:
_MM_ALIGN16 struct Sphere
{
// ....
Vector3 point;
float radius
};
Run Code Online (Sandbox Code Playgroud)
这似乎首先解决了这个问题.但在更改了一些代码后,我的程序又开始以奇怪的方式崩溃.我在网上搜索了一些,发现了一篇博客文章.我尝试了作者Ernst Hot为解决这个问题做了什么,它对我也有用.我在我的类中添加了new和delete运算符,如下所示:
_MM_ALIGN16 struct Sphere
{
// ....
void *operator new (unsigned int size)
{ return _mm_malloc(size, 16); }
void operator delete (void *p)
{ _mm_free(p); }
Vector3 point;
float radius
};
Run Code Online (Sandbox Code Playgroud)
恩斯特提到这种方法也可能存在问题,但他只是链接到一个不再存在的论坛,而没有解释为什么它可能会有问题.
所以我的问题是:
定义运算符有什么问题?
为什么不添加_MM_ALIGN16足够的类定义?
处理SSE内在函数的对齐问题的最佳方法是什么?
有谁知道一个开源的C++ x86 SIMD内在函数库?
英特尔在其集成性能原语库中提供了我所需要的,但由于版权所有,我无法使用它.
编辑
我已经知道编译器提供的内在函数了.我需要的是一个方便的界面来使用它们.
为什么在JVM内部类中存在的某些代码模式被转换为内部函数,而从我自己的类调用时相同的模式则不然.
例:
bitCount函数,当从Integer.bitCount(i)内调用时,将变成一个内在函数.但是当复制到我的类中然后调用将需要更长的时间来执行.
相比
Integer.bitCount(i)
MyClass.bitCount(i)
public static int bitCount(int i) {
// HD, Figure 5-2
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
Run Code Online (Sandbox Code Playgroud) intrinsics ×10
c++ ×7
sse ×4
c ×3
simd ×3
alignment ×1
arm ×1
assembly ×1
clang ×1
demoscene ×1
header-files ×1
java ×1
jvm ×1
memset ×1
neon ×1
performance ×1
visual-c++ ×1
x86 ×1