首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SSE本质检查零标志

SSE本质检查零标志
EN

Stack Overflow用户
提问于 2016-11-12 14:01:59
回答 2查看 820关注 0票数 3

我想知道是否可以通过Intel的SSE内部函数来检查处理器的标志注册?

例如:

代码语言:javascript
复制
int idx = _mm_cmpistri(mmrange, mmstr, 0x14);
int zero = _mm_cmpistrz(mmrange, mmstr, 0x14);

在本例中,编译器能够将这两个本质优化为一个指令(pcmpistri),并通过跳转指令(jz)检查注册的标志。

但是,在下面的示例中,编译器无法正确地优化代码:

代码语言:javascript
复制
__m128i mmmask = _mm_cmpistrm(mmoldchar, mmstr, 0x40);
int zero = _mm_cmpistrz(mmoldchar, mmstr, 0x40);

在这里,编译器生成一个pcmpistrm和一个pcmpistri指令。但是,在我看来,第二条指令是多余的,因为pcmpistrm以与pcmistri相同的方式设置处理器标志寄存器中的标志。

因此,回到我的问题上,是否有一种方法可以直接读取标志寄存器,或者指示编译器只生成一个pcmpistrm指令?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-12 20:41:11

看起来只是MSVC错过了优化错误,而不是任何固有的缺陷。

gcc6.2和icc17在我编写的zero结果分支(关于戈德波特编译器浏览器 )测试函数中成功地使用了来自一个PCMPISTRM的两个结果

代码语言:javascript
复制
#include <immintrin.h>
__m128i foo(__m128i mmoldchar, __m128i mmstr)
{      
  __m128i mmmask = _mm_cmpistrm(mmoldchar, mmstr, 0x40);
  int zero = _mm_cmpistrz(mmoldchar, mmstr, 0x40);
  if(zero)
    return mmmask;
  else
    return _mm_setzero_si128();
}

    ##gcc6.2 -O3 -march=nehalem
    pcmpistrm       xmm0, xmm1, 64
    je      .L5
    pxor    xmm0, xmm0
    ret
.L5:
    ret

OTOH,clang3.9无法通过CSE,并使用PCMPISTRI。

代码语言:javascript
复制
foo:
    movdqa  xmm2, xmm0
    pcmpistri       xmm2, xmm1, 64
    pxor    xmm0, xmm0
    jne     .LBB0_2
    pcmpistrm       xmm2, xmm1, 64
.LBB0_2:
    ret

注意,根据阿格纳福格(氏)指令表的说法,PCMPISTRM具有很好的吞吐量,但是延迟时间很大,所以如果延迟是瓶颈的话,还有很多空间可以并行完成。像使用__readflags()这样的跳槽可能会更糟。

票数 2
EN

Stack Overflow用户

发布于 2016-11-12 20:23:40

我自己找到了解决办法。

有一个函数来读取标志寄存器,称为__readeflags()。它封装了pushf (pushfq on x64 plattforms)指令。

代码现在如下所示:

代码语言:javascript
复制
__m128i mmmask = _mm_cmpistrm(mmoldchar, mmstr, 0x40);
int zero = __readeflags() & 0x40; //0x40 is the mask for the zero flag (bit 6)

这个解决方案并不是最优的,但它做到了这一点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40563615

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档