首页 > 解决方案 > 在不同的浮点精度之间切换时使用我自己的 std::mersenne_twister_engine 模板参数

问题描述

std::mt19937是一个 typedefstd::mersenne_twister_engine。如果我在采样中切换不同的浮点精度,我应该为后者使用我自己的模板参数吗?如果是这样,怎么做?

现在我有这样的东西

#include <random>
#include <iostream>

int main()
{
    using float_type = double;

    std::random_device rd;  
    std::mt19937 gen(rd()); 
    std::uniform_real_distribution<float_type> dis(1.0, 2.0);
    for (int n = 0; n < 1e6; ++n) {
        std::cout << dis(gen) << ' ';
    }
    std::cout << '\n';
}

但是当我切换using float_type = double;using float_type = float;时并没有太大的加速。实际上,在我拥有的其他一些代码中,使用float实际上要慢得多!

如果有帮助,这是一个makefile。我time ./prog在编译后使用make了一个粗略的计时器,我运行的是 Ubuntu 18.04.2 LTS,我的处理器是 Intel® Xeon(R) CPU E3-1241 v3 @ 3.50GHz × 8。

PROG = prog
SRCS = main.cpp
OBJS = main.o
CXX = g++
CXXFLAGS = -std=c++11 -O3 $(INCLUDES) -pg


all: $(PROG)

$(PROG): $(OBJS)
        $(CXX) -o $@ $(OBJS) 

main.cpp :
        $(CXX) $(CXXFLAGS) -c 

main.o : main.cpp
        $(CXX) $(CXXFLAGS) -c main.cpp

.PHONY: clean
clean:
        rm -f $(PROG) $(OBJS) 

标签: c++c++11randommersenne-twister

解决方案


如果我在采样中切换不同的浮点精度,我应该为后者使用我自己的模板参数吗?如果是这样,怎么做?

当然,您可以使用 64 位引擎进行双精度采样(尾数为 53 位长),使用 32 位引擎进行浮点采样。

#define USE_DOUBLES

...

#ifdef USE_DOUBLES
    using float_type = double;
    using rng        = std::mt19937_64;
#else
    using float_type = float;
    using rng        = std::mt19937;
#endif

mt19937_64是 MT 的别名,每次调用生成 64 位随机性


推荐阅读