Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/152.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 零上限导致不正确的结果_C++_Gcc_Mingw_Avx_Avx2 - Fatal编程技术网

C++ 零上限导致不正确的结果

C++ 零上限导致不正确的结果,c++,gcc,mingw,avx,avx2,C++,Gcc,Mingw,Avx,Avx2,我在for循环中有以下代码 dataInt = _mm_loadu_si128((__m128i *) (&x[i])); __m256i val_unpacked = _mm256_cvtepi16_epi32(dataInt); __m256 converted = _mm256_cvtepi32_ps(val_unpacked); converted = _mm256_div_ps(converted, _mm256_set1_ps(max_val

我在for循环中有以下代码

    dataInt = _mm_loadu_si128((__m128i *) (&x[i]));
    __m256i val_unpacked = _mm256_cvtepi16_epi32(dataInt);
    __m256 converted = _mm256_cvtepi32_ps(val_unpacked);

    converted = _mm256_div_ps(converted, _mm256_set1_ps(max_val));

    _mm256_storeu_ps(&y[i], converted);
    _mm256_zeroupper();
它基本上只是将int16的向量转换为[-1,1]范围内的浮点(max_val是常量变量,等于numeric_limit::max)

我在posix线程版本7.2中使用mingw编译器

当我在没有优化的情况下编译程序时,它运行得很好,但当我打开优化时(我无法控制单个优化,它在我正在处理的项目中,但应该使用优化的lvl-O3),我开始得到错误的结果

问题出在zeroupper指令中。当我在优化模式下移除它时,它再次给出正确的结果

貌似,优化不尊重ZeoupPress指令的位置,并将其调用在环的中间,而不是在末尾的某个地方,从而丢弃有用的数据。这样可能吗?我在网上找不到关于这个话题的任何讨论

编辑:我提取了代码。看起来是这样的:

#include <iostream>
#include <limits>
#include <immintrin.h>
#include <xmmintrin.h>  
 int  __attribute__ ((__target__ ("avx2,sse4.2"))) main(){

/*volatile*/ float max_val = static_cast<float> (std::numeric_limits<int16_t>::max());

__m128i dataInt;
int runs = 32;
int16_t source[32];
float target[32];
int i = 0;
for (; i < 32; ++i) {
    source[i] = std::numeric_limits<int16_t>::min()+i;
}

i=0;
for (; i < runs; i += 8) {
    // _mm256_zeroupper();

     dataInt = _mm_loadu_si128((__m128i *) (&source[i]));

      __m256i val_unpacked =_mm256_cvtepi16_epi32(dataInt);
    __m256 converted =  _mm256_cvtepi32_ps(val_unpacked);

    __m256 maxVinFloat = _mm256_set1_ps(max_val);
    converted = _mm256_div_ps(converted, maxVinFloat);

    _mm256_storeu_ps(&target[i], converted);
    _mm256_zeroupper();
}
i = 0;
for (; i < 32; ++i) {
    std::cout << target [ i ] <<"  ";
}}
#包括
#包括
#包括
#包括
int属性主{
/*volatile*/float max\u val=静态强制转换(std::numeric\u limits::max());
__m128i数据点;
int=32;
int16_t源[32];
浮动目标[32];
int i=0;
对于(;i<32;++i){
source[i]=std::numeric_limits::min()+i;
}
i=0;
对于(;i<运行;i+=8){
//_mm256_zeropper();
dataInt=_mm_loadu_si128((_m128i*)(&source[i]);
__m256i val_Unpacketed=_mm256_cvtepi16_epi32(数据点);
__m256转换=_mm256_cvtepi32_ps(val_解包);
__m256最大浮点=_mm256_set1_ps(最大值);
已转换=_mm256_div_ps(已转换,最大浮点);
_mm256存储系统(与目标[i],已转换);
_mm256_zeropper();
}
i=0;
对于(;i<32;++i){

std::您是否通常不需要手动插入
\u mm256\u zeropper()
。编译器根据需要插入
vzeropper
asm指令。但仍然是一个有趣的问题;我希望GCC尊重
\u mm256\u zeropper()在源中放置并将其归为当时范围内的每一个'````M256 ''的上半部分。你能给这个问题加上足够的C++代码,使我们可以复制/粘贴到编译器中,例如在AN上,并查看ASM输出?@彼得科尔德正在研究它,但似乎提取代码消除了问题。e更多的时间(我现在没有)。我的初衷是快速扫描我的选项,以了解是否有其他人以前处理过这个问题,或者这是否是一个已知的问题。但似乎我必须深入挖掘。@PeterCordes我添加了函数的提取版本。