我正在使用Intel Ivy Bridge CPU,希望使用RDRAND操作码(https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide)在C#中。
如何通过C#调用此CPU指令?我在这里看到了一个从c#执行汇编代码的示例:C#中的x86/x64 CPUID
但是我不确定如何将其用于RDRAND。代码不需要检查执行代码的CPU是否支持该指令。
我见过这个来自英特尔drng_samples的执行汇编字节码的C示例:
int rdrand32_step (uint32_t *rand)
{
unsigned char ok;
/* rdrand edx */
asm volatile(".byte 0x0f,0xc7,0xf0; setc %1"
: "=a" (*rand), "=qm" (ok)
:
: "edx"
);
return ok;
}
如何将在C#中执行汇编代码的示例与来自Inteldrng
示例代码的C代码结合起来?
SO上有一些答案,可以在运行时生成(非托管)汇编代码,供托管代码回调。这很有趣,但我建议您为此目的简单地使用C /CLI,因为它旨在简化互操作场景。创建一个新的Visual C CLR类库并为其提供一个rdrandwrapper.cpp
:
#include <immintrin.h>
using namespace System;
namespace RdRandWrapper {
#pragma managed(push, off)
bool getRdRand(unsigned int* pv) {
const int max_rdrand_tries = 10;
for (int i = 0; i < max_rdrand_tries; ++i) {
if (_rdrand32_step(pv)) return true;
}
return false;
}
#pragma managed(pop)
public ref class RandomGeneratorError : Exception
{
public:
RandomGeneratorError() : Exception() {}
RandomGeneratorError(String^ message) : Exception(message) {}
};
public ref class RdRandom
{
public:
int Next() {
unsigned int v;
if (!getRdRand(&v)) {
throw gcnew RandomGeneratorError("Failed to get hardware RNG number.");
}
return v & 0x7fffffff;
}
};
}
这是一个非常简单的实现,只是试图模仿随机。接下来,获取一个非负随机整数。根据问题,它不会尝试验证CPU上的RDRAND是否实际可用,但它会处理指令存在但无法工作的情况。(在当前硬件上,“不会发生”这种情况,除非它坏了,如下所述。)
生成的程序集是一个混合程序集,可由托管C#代码使用。确保将程序集编译为x86或x64,与非托管代码相同(默认情况下,项目设置为编译为“任何CPU”,这将无法正常工作,因为非托管代码只有一个特定位)。
using System;
using RdRandWrapper;
class Program {
static void Main(string[] args) {
var r = new RdRandom();
for (int i = 0; i != 10; ++i) {
Console.WriteLine(r.Next());
}
}
}
我对性能没有任何要求,但可能不是很好。如果希望以这种方式获取多个随机值,则可能需要一个Next(int[]values)
重载来在一次调用中获取多个随机值,以减少互操作的开销。
今天我想:好吧,即使人们对NIST SP 800-90A的RDRAND实现有很大的怀疑,它仍然是伪随机数生成器(PRNG)的硬件实现,对于非敏感应用程序来说必须足够好。所以我想在我的比赛中使用它,而不是Mersenne Twister。 因此,为了查看使用该指令是否有任何性能提升,我比较了以下两个代码的时间: 和 通过运行这两个,我得到: 所以,Mersenne Twister在我的CPU上比RD
如何使用Java中的Intel AVX矢量指令集?这是一个简单的问题,但答案似乎很难找到。
我在看H.J.Lu的补丁:更新x86 rdrand intrinsics。我不知道我是否应该使用rdrand\u64、rdrand64\u步骤,或者是否有其他功能。似乎没有为他们编写测试用例。 似乎也缺乏手册页(来自Ubuntu 14,GCC 4.8.4): 如何使用RDRAND内部函数来生成一个32字节的块? 一个相关的问题是RDRAND和RDSEED内部函数GCC和Intel C。但它没有告诉
我费了很大的劲才让它运转起来: 我尝试了以下方法: 我会得到: 显然,编译器将< code>%0替换为< code>%register,但仍然保留< code>'%'... 因此,我决定将 % 替换为 ,将 替换为 : 并得到结果错误: 我怀疑编译器优化了东西并内联了被调用的函数(所以没有雷特),但仍然不知道我该怎么做。 注意:我不能把编译器从clang改成gcc,因为用clang 11的不是我而
我有一个带有四个麦克风卡(mic0-mic3)的服务器,它工作得很好。我想禁用一些麦克风,例如mic3,现在只有mic0-mic2可用。我该怎么办?
Intel内存型号保证: 门店不会与其他门店一起重新订购 货物不会与其他货物一起重新订购 http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/ 我看到有人声称由于英特尔内存模型,SFENCE在x86-64上是多余的,但从来没有LFENCE。上述内存模型规则是否使任一指令冗余?