相关疑难解决方法(0)

如何选择AVX比较谓词变体

在高级向量扩展(AVX)中,比较指令如_m256_cmp_ps,最后一个参数是比较谓词.谓词的选择压倒了我.它们似乎是类型,排序,信号的三重奏.例如_CMP_LE_OS是'小于或等于,有序,信令.

对于初学者来说,是否存在选择信令或非信令的性能原因,同样,有序或无序的速度比另一个更快?

什么'非信令'甚至意味着什么?我根本无法在文档中找到这个.任何关于何时选择什么的经验法则?

以下是avxintrin.h的谓词选择:

/* Compare */
#define _CMP_EQ_OQ    0x00 /* Equal (ordered, non-signaling)  */
#define _CMP_LT_OS    0x01 /* Less-than (ordered, signaling)  */
#define _CMP_LE_OS    0x02 /* Less-than-or-equal (ordered, signaling)  */
#define _CMP_UNORD_Q  0x03 /* Unordered (non-signaling)  */
#define _CMP_NEQ_UQ   0x04 /* Not-equal (unordered, non-signaling)  */
#define _CMP_NLT_US   0x05 /* Not-less-than (unordered, signaling)  */
#define _CMP_NLE_US   0x06 /* Not-less-than-or-equal (unordered, signaling)  */
#define _CMP_ORD_Q    0x07 /* Ordered (nonsignaling)   */
#define _CMP_EQ_UQ    0x08 /* Equal (unordered, non-signaling)  */
#define …
Run Code Online (Sandbox Code Playgroud)

simd avx

35
推荐指数
2
解决办法
7360
查看次数

x86汇编程序:浮点比较

作为编译器项目的一部分,我必须为x86编写GNU汇编代码来比较浮点值.我试图找到有关如何在线进行此操作的资源,据我所知,它的工作原理如下:

假设我要比较的值是浮点堆栈上的唯一值,那么fcomi指令将比较这些值并设置CPU标志,以便je可以使用...指令.

我问,因为这只会有效.例如:

.section    .data
msg:    .ascii "Hallo\n\0"
f1:     .float 10.0
f2:     .float 9.0

.globl main
    .type   main, @function
main:
    flds f1
    flds f2
    fcomi
    jg leb
    pushl $msg
    call printf
    addl $4, %esp
leb:
    pushl $0
    call exit
Run Code Online (Sandbox Code Playgroud)

即使我认为应该打印"Hallo"也不会打印,如果你切换f1和f2,它仍然不会是一个逻辑上的矛盾.jne并且jl但是似乎做工精细.

我究竟做错了什么?

PS:fcomip只弹出一个值还是同时弹出?

floating-point x86 assembly compare gnu-assembler

15
推荐指数
1
解决办法
1万
查看次数

clang的`-Ofast`选项在实践中有什么作用,尤其是与gcc的差异?

类似于问题gcc的ffast-math实际上做了什么?并且与Clang优化级别的SO问题有关,我想知道在实际条件下优化是做什么clang-Ofast,以及它们是否与gcc完全不同,或者这是否依赖于编译器依赖于硬件.

根据clang优化级别的公认答案,-Ofast增加了-O3优化:-fno-signed-zeros -freciprocal-math -ffp-contract=fast -menable-unsafe-fp-math -menable-no-nans -menable-no-infs.这似乎完全与浮点数学相关.但是这些优化对于像C++这样的事物来说意味着什么呢?像英特尔酷睿i7这样的CPU上的浮点数通用数学函数以及这些差异有多可靠?

例如,实际上:

该代码std::isnan(std::numeric_limits<float>::infinity() * 0)返回真正的我-O3.我相信这是符合IEEE数学标准的结果.

随着-Ofast不过,我得到一个错误的返回值.此外,该操作(std::numeric_limits<float>::infinity() * 0) == 0.0f返回true.

我不知道这是否与gcc中看到的相同.我不清楚结果如何依赖于结构,也不清楚编译器如何依赖它们,也不清楚是否存在任何适用的标准-Ofast.

如果有人可能会产生类似于一组单元测试代码公案来解决这个问题,那可能是理想的.我已经开始做这样的事情,但宁愿不重新发明轮子.

c++ floating-point x86-64 clang compiler-optimization

9
推荐指数
1
解决办法
2830
查看次数

使用英特尔SSE执行分支的最佳方法是什么?

我正在编写一个编译器,我必须输出浮点值的分支条件代码.例如,要编译这种代码:

if(a <= b){
    //1. DO something
} else {
    //2. Do something else
}
Run Code Online (Sandbox Code Playgroud)

当a和b是浮点变量时.如果条件不正确,我只需要跳到2,否则降到1.我正在考虑编译器级别的优化,考虑1和2中的内容.

我需要一些适用于所有比较运算符的东西>,> =,<,<=,==和!=

我发现进行比较的一种方法是使用CMPLTSD(以及其他关系运算符的其他等效指令).但是,我必须使用SSE寄存器,特别是结果,然后我必须在通用寄存器(例如eax)上移动它的值,最后将值与0进行比较.

我还看到UCOMISD指令应该正确设置标志,但显然它不像我想象的那样工作.

那么,处理这样的代码的最佳方法是什么?有没有比我的第一个解决方案更好的指示?

最好的,我的意思是,这个问题的一般解决方案.如果可能的话,我希望代码的行为与对整数进行比较的方式相同(cmp a,b; jge label).当然,我更希望用最快的指令来实现这一目标.

compiler-construction assembly sse intel

6
推荐指数
1
解决办法
1520
查看次数

使用 simd 在双打数组中找到 nan

这个问题非常类似于:

用于浮点相等比较的 SIMD 指令(使用 NaN == NaN)

尽管该问题侧重于 128 位向量,并且对识别 +0 和 -0 有要求。

我有一种感觉,我自己可能会得到这个,但英特尔内在指南页面似乎已关闭:/

我的目标是获取一个双精度数组并返回数组中是否存在 NaN。我预计大多数情况下不会有一条路线,并希望该路线具有最佳性能。

最初,我打算对自己进行 4 个双打的比较,反映用于 NaN 检测的非 SIMD 方法(即 NaN 只有值为a != atrue 的值)。就像是:

data *double = ...
__m256d a, b;
int temp = 0;

//This bit would be in a loop over the array
//I'd probably put a sentinel in and loop over while !temp
a = _mm256_loadu_pd(data);
b = _mm256_cmp_pd(a, a, _CMP_NEQ_UQ);
temp = temp | _mm256_movemask_pd(b);
Run Code Online (Sandbox Code Playgroud)

但是,在一些比较示例中,除了比较本身之外,似乎还进行了某种 NaN 检测。我简单地想,如果像这样的东西 _CMP_EQ_UQ …

c sse simd nan avx

6
推荐指数
1
解决办法
248
查看次数

什么是有序和无序LLVM CmpInst比较指令?

描述LLVM中比较指令类型的CmpInst::Predicate类型定义"llvm/IR/InstrTypes.h"如下:

enum Predicate {
  // Opcode              U L G E    Intuitive operation
  FCMP_FALSE =  0,  ///< 0 0 0 0    Always false (always folded)
  FCMP_OEQ   =  1,  ///< 0 0 0 1    True if ordered and equal
  FCMP_OGT   =  2,  ///< 0 0 1 0    True if ordered and greater than
  FCMP_OGE   =  3,  ///< 0 0 1 1    True if ordered and greater than or equal
  FCMP_OLT   =  4,  ///< 0 1 0 0    True …
Run Code Online (Sandbox Code Playgroud)

llvm

5
推荐指数
1
解决办法
1042
查看次数