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

如何使用英特尔的RDRAND使用内联组装。网

韦衡
2023-03-14

我正在使用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代码结合起来?

共有1个答案

郭华美
2023-03-14

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。上述内存模型规则是否使任一指令冗余?