当前位置: 首页 > 知识库问答 >
问题:

各种编译器上的RDRAND和RDSEED内部函数?

高嘉树
2023-03-14

英特尔C编译器和/或GCC是否像2012/2013年以来的MSVC一样支持以下英特尔内部函数

#include <immintrin.h>  // for the following intrinsics
int _rdrand16_step(uint16_t*);
int _rdrand32_step(uint32_t*);
int _rdrand64_step(uint64_t*);
int _rdseed16_step(uint16_t*);
int _rdseed32_step(uint32_t*);
int _rdseed64_step(uint64_t*);

如果支持这些内部函数,那么支持哪个版本(请使用编译时常量)?

共有3个答案

巴帅
2023-03-14

所有主要编译器都支持Intel的Intrinsic forrdrandrdseedvia

#include <immintrin.h>
#include <stdint.h>

// gcc -march=native or haswell or znver1 or whatever, or manually enable -mrdrnd
uint64_t rdrand64(){
    unsigned long long ret;   // not uint64_t, GCC/clang wouldn't compile.
    do{}while( !_rdrand64_step(&ret) );  // retry until success.
    return ret;
}

// and equivalent for _rdseed64_step
// and 32 and 16-bit sizes with unsigned and unsigned short.

当指令在编译时启用时,某些编译器会定义指令。GCC/clang,因为它们完全支持内在的,但只是在很久以后才支持ICC(19.0)。对于ICC,直到2021年1月,march=ivybridge并不意味着mrdrnd或定义
ICX基于LLVM,其行为类似于clang
MSVC不定义任何宏;它对内部函数的处理仅围绕运行时特性检测进行设计,不像gcc/clang那样简单的方法是编译时CPU特性选项。

为什么{}while()而不是{code>while(){}?事实证明,ICC使用do{}while()编译成一个不那么愚蠢的循环,而不是无用地剥离第一次迭代。其他编译器无法从这种牵手操作中获益,这对ICC来说也不是一个正确性问题。

为什么要使用无符号long long而不是uint64\u t?该类型必须与内部函数所期望的指针类型一致,否则无论对象表示是否相同(64位无符号),C编译器尤其是C编译器都会抱怨。例如,在Linux上,uint64\u t是无符号long,但GCC/clang是immintrin。h定义int rdrand64\u步长(无符号长-长*),与在Windows上相同。所以您总是需要带有GCC/clang的无符号long-long-ret。MSVC没有问题,因为它只能(AFAIK)针对Windows,其中无符号long long是唯一的64位无符号类型<但是根据我在上的测试,在为GNU/Linux编译时,ICC将内部定义为采用无符号长*https://godbolt.org/.因此,要移植到ICC,实际上需要ifdef英特尔编译器;即使在C语言中,我也不知道如何使用自动或其他类型的演绎来声明与其匹配的变量。

在螺栓上测试;MSVC的最早版本是2015年,ICC是2013年,所以我不能再回头了。在任何给定的编译器中,都同时引入了对rdrand16\step的支持。64需要64位模式。

姬魁
2023-03-14

Microsoft编译器不支持RDSEED和RDRAND指令的内部函数

但是,您可以使用NASM或MASM实现这些指令。汇编代码可在以下位置获得:

https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide

对于“英特尔编译器”,可以使用标头确定版本。可以使用以下宏来确定版本和子版本:

__INTEL_COMPILER //Major Version
__INTEL_COMPILER_UPDATE // Minor Update.

例如,如果使用ICC15.0 Update 3编译器,它将显示

__INTEL_COMPILER  = 1500
__INTEL_COMPILER_UPDATE = 3

有关预定义宏的更多详细信息,请访问:https://software.intel.com/en-us/node/524490

闽承望
2023-03-14

GCC和Intel编译器都支持它们。GCC支持于2010年底引入。它们需要标头

GCC支持至少从4.6版开始就存在了,但似乎没有任何特定的编译时常量-您只需检查\uuu GNUC\u MAJOR__

 类似资料:
  • 我在看H.J.Lu的补丁:更新x86 rdrand intrinsics。我不知道我是否应该使用rdrand\u64、rdrand64\u步骤,或者是否有其他功能。似乎没有为他们编写测试用例。 似乎也缺乏手册页(来自Ubuntu 14,GCC 4.8.4): 如何使用RDRAND内部函数来生成一个32字节的块? 一个相关的问题是RDRAND和RDSEED内部函数GCC和Intel C。但它没有告诉

  • 最近的Intel芯片(Ivy Bridge及以上)有生成(伪)随机位的指令<代码>RDSEED输出从芯片上传感器收集的熵生成的“真实”随机位输出由真随机数生成器播种的伪随机数生成器生成的位。根据英特尔的文档,RDSEED速度较慢,因为收集熵的成本很高。因此,RDRAND作为一种更便宜的替代方案提供,其输出对于大多数加密应用程序来说是足够安全的。(这类似于Unix系统上的开发/随机(dev/rand

  • 我正在使用英特尔SSE/AVX/FMA内部函数来实现一些数学函数的完美内联SSE/AVX指令。 给定以下代码 clang 3.9生成的程序集-march=x86-64-mfma-O3 虽然为sqrt生成的代码很好,但与std fma(依赖于编译器内部std::fma)相比,fma中存在不必要的VxORP(将绝对未使用的xmm3寄存器设置为零)和MOVS指令 GCC 6.2生成的程序集-march=

  • 文章信息 本文地址:http://blog.keras.io/building-autoencoders-in-keras.html 本文作者:Francois Chollet 什么是自动编码器(Autoencoder) 自动编码器是一种数据的压缩算法,其中数据的压缩和解压缩函数是1)数据相关的,2)有损的,3)从样本中自动学习的。在大部分提到自动编码器的场合,压缩和解压缩的函数是通过神经网络实现

  • 我有一个编译器错误问题,请查看以下代码: 问题在于编译器忽略了 foo 函数上的“const”,使得对 foo 的调用非法(const int* to int*)。 严重程度代码描述项目文件行抑制状态错误C2664'ululfoo(const::类型)':无法将参数1从'const int*'转换为'const Mystrt::类型' 我在Visual Studio和gcc的5.3编译器中测试了以

  • 我知道这依赖于JVM,每个虚拟机都会选择实现它,但我想了解总体概念。 据说对于JVM用来执行Java程序的内存段 Java堆栈 不一定用连续内存实现,并且可能都实际分配在操作系统提供的一些堆内存上,这就引出了我的问题。 完全使用JIT机制并将字节码方法编译为本机机器码方法的JVM将这些方法存储在某个地方,那会在哪里?执行引擎(通常用C/C编写)将不得不调用这些JIT编译函数,然而内核不应该允许程序