在详细说明之前,我有以下功能,
Let _e, _w be an array of equal size. Let _stepSize be of float type.
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 选项 likely be in GCC, Clang, and ICC soon (if not already) :
-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 only appears to define __AVX__ and __AVX2__ .
在您的情况下,您的代码似乎只使用 SSE2,因此如果您在 64 位模式下编译(这是 64 位用户空间中的默认模式或明确使用 -m64
),则 __SSE2__
已定义。但由于您使用了 -msse4a
,因此 __SSE4A__
也将被定义。
请注意,启用指令与确定指令集是否可用不同。如果您希望您的代码适用于多个指令集,那么 I suggest a CPU dispatcher .
关于c++ - 确定什么内在标志被激活,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27219966/