确定激活了哪个内部标志
Determine what intrinsic flag is activated
在我详细说明细节之前,我有以下功能,
让_e,_w是一个大小相等的数组。让_stepSize为浮点型。
void GradientDescent::backUpWeights(FLOAT tdError) {
AI::FLOAT multiplier = _stepSize * tdError;
for (UINT i = 0; i < n; i++){
_w[i] += _e[i]*multiplier
}
// Assumed that the tilecode ensure that _w.size() or _e.size() is even.
}
这个函数很好,但是如果一个 cpu 有内在的,特别是对于这个例子,SSE4,那么下面的函数允许我缩短秒数(对于相同的输入(,即使已经包含 -O3 gcc 标志为两者和额外的 -msse4a 为此添加了。
void GradientDescent::backUpWeights(FLOAT tdError) {
AI::FLOAT multiplier = _stepSize * tdError;
__m128d multSSE = _mm_set_pd(multiplier, multiplier);
__m128d* eSSE = (__m128d*)_e;
__m128d* wSSE = (__m128d*)_w;
size_t n = getSize()>>1;
for (UINT i = 0; i < n; i++){
wSSE[i] = _mm_add_pd(wSSE[i],_mm_mul_pd(multSSE, eSSE[i]));
}
// Assumed that the tilecode ensure that _w.size() or _e.size() is even.
}
问题:
我现在的问题是我想要这样的东西,
void GradientDescent::backUpWeights(FLOAT tdError) {
AI::FLOAT multiplier = _stepSize * tdError;
#ifdef _mssa4a_defined_
__m128d multSSE = _mm_set_pd(multiplier, multiplier);
__m128d* eSSE = (__m128d*)_e;
__m128d* wSSE = (__m128d*)_w;
size_t n = getSize()>>1;
for (UINT i = 0; i < n; i++){
wSSE[i] = _mm_add_pd(wSSE[i],_mm_mul_pd(multSSE, eSSE[i]));
}
#else // No intrinsic
for (UINT i = 0; i < n; i++){
_w[i] += _e[i]*multiplier
}
#endif
// Assumed that the tilecode ensure that _w.size() or _e.size() is even.
}
因此,如果在 gcc 中,我声明了 -msse4a 来编译这段代码,那么它将选择在 if 语句中编译代码。当然,我的计划是为所有内在的实现它,而不仅仅是上面的SSE4A。
GCC、ICC(在 Linux 上(和 Clang 有以下编译选项和相应的定义
options define
-mfma __FMA__
-mavx2 __AVX2__
-mavx __AVX__
-msse4.2 __SSE4_2__
-msse4.1 __SSE4_1__
-mssse3 __SSSE3__
-msse3 __SSE3__
-msse2 __SSE2__
-m64 __SSE2__
-msse __SSE__
在 GCC 和 Clang 中选项和定义,但在 ICC 中没有:
-msse4a __SSE4A__
-mfma4 __FMA4__
-mxop __XOP__
在最新版本的 GCC、Clang 和 ICC 中定义的 AVX512 选项
-mavx512f __AVX512F__ //foundation instructions
-mavx512pf __AVX512PF__ //pre-fetch instructions
-mavx512er __AVX512ER__ //exponential and reciprocal instructions
-mavx512cd __AVX512CD__ //conflict detection instructions
AVX512选项可能很快就会出现在GCC,Clang和ICC中(如果还没有的话(:
-mavx512bw __AVX512BW__ //byte and word instructions
-mavx512dq __AVX512DQ__ //doubleword and quadword Instructions
-mavx512vl __AVX512VL__ //vector length extensions
请注意,这些交换机中的许多支持更多:例如-mfma
启用和定义AVX2,AVX,SSE4.2 SSE4.1,SSSE3,SSE3,SSE2,SSE。
我不是 100% AVX512 的 ICC 编译器选项是什么。它可以是-xMIC-AVX512
而不是-mavx512f
.
MSVC 似乎只定义了__AVX__和__AVX2__。
在您的情况下,您的代码似乎只使用 SSE2,因此如果您在 64 位模式下编译(这是 64 位用户空间中的默认设置或使用 -m64
显式编译(,则定义__SSE2__
。但是既然你使用了-msse4a
那么__SSE4A__
也会被定义。
请注意,启用指令与确定指令集是否可用不同。如果您希望您的代码在多个指令集上运行,那么我建议您使用 CPU 调度程序。
后来我才知道没有办法做到这一点。 不过,一个简单而优雅的方式是这样的。对于具有 sse4a 内部函数的 x86-64 平台,请执行以下 make 目标规则(假设您将内部源存储在 src/intrinsic/中,并将构建(.o 文件(存储在 build/* 中(:
CXX=g++ -O3
CXXFLAGS=-std=c++14 -Wunused
CPPFLAGS=
CPP_INTRINSIC_FLAG:=-ffast-math
INTRINSIC_OBJECT := $(patsubst src/intrinsic/%.cpp,build/%.o,$(wildcard src/intrinsic/*.cpp))
x86-64-sse4: $(eval CPP_INTRINSIC_FLAG+=-msse4a -DSSE4A) $(INTRINSIC_OBJECT)
# Intrinsic objects
build/%.o: src/intrinsic/%.cpp
$(CXX) $(CXXFLAGS) -c $(CPPFLAGS) $(CPP_INTRINSIC_FLAG) $(INCLUDE_PATHS) $^ -o $@
- 将函数类成员映射到类本身内部
- Boost Spirit,获取迭代器内部语义动作
- 我不明白为什么我声明一个空的内部结构并将其传递给构造函数
- 内联函数中具有内部链接的全局变量
- 在函数内部的声明中初始化数组,并在外部使用它
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 卷曲bracers内部结构的声明
- 从函数角度看ID到文件路径的内部与外部映射
- spdlog标头仅与外部fmt一起使用.spdlog错误:'内部':不是'fmt'
- 如何在pugixml中获取节点的内部XML
- 使用C链接在函数内部创建C++模板
- 指针没有更新它在void函数内部指向的值
- 方法内部但循环仍得到预期的不合格id错误C++
- C++:具有内部链接的正向声明常量
- 即使使用调试编译标志,表达式也是"optimized out"
- 在 CMake 中为每个目标设置编译器/链接器标志
- SDL_PollEvent() 无法捕获类函数内部SDL_QUIT?
- 有关使用标志位设置内部错误标志的说明
- 确定激活了哪个内部标志
- 正在将链接器标志发送到ndk内部版本