为什么我的C++代码比R慢得多?

 星期五2502915743 发布于 2023-01-17 14:28

我在R和C++中编写了以下代码,它们执行相同的算法:

a)模拟随机变量X 500次.(X值为0.9,概率为0.5,1.1值为0.5)

b)将这500个模拟值相乘得到一个值.将该值保存在容器中

c)重复10000000次,使容器具有10000000个值

R:

ptm <- proc.time()
steps <- 500
MCsize <- 10000000
a <- rbinom(MCsize,steps,0.5)
b <- rep(500,times=MCsize) - a
result <- rep(1.1,times=MCsize)^a*rep(0.9,times=MCsize)^b
proc.time()-ptm

C++

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

const size_t MCsize = 10000000;
std::mutex mutex1;
std::mutex mutex2;
unsigned seed_;
std::vector cache;

void generatereturns(size_t steps, int RUNS){
    mutex2.lock();
    // setting seed
    try{    
        std::mt19937 tmpgenerator(seed_);
        seed_ = tmpgenerator();
        std::cout << "SEED : " << seed_ << std::endl;
    }catch(int exception){
        mutex2.unlock();
    }
    mutex2.unlock();

    // Creating generator
    std::binomial_distribution distribution(steps,0.5);
    std::mt19937 generator(seed_);

    for(int i = 0; i!= RUNS; ++i){
        double power;
        double returns;
        power = distribution(generator);
        returns = pow(0.9,power) * pow(1.1,(double)steps - power);
        std::lock_guard guard(mutex1);
        cache.push_back(returns);
    }
}    


int main(){
    std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
    size_t steps = 500;
    seed_ = 777;    

    unsigned concurentThreadsSupported = std::max(std::thread::hardware_concurrency(),(unsigned)1);
    int remainder = MCsize % concurentThreadsSupported;

    std::vector threads;
    // starting sub-thread simulations
    if(concurentThreadsSupported != 1){
        for(int i = 0 ; i != concurentThreadsSupported - 1; ++i){
            if(remainder != 0){
                threads.push_back(std::thread(generatereturns,steps,MCsize /     concurentThreadsSupported + 1));
                remainder--;
            }else{
                threads.push_back(std::thread(generatereturns,steps,MCsize /     concurentThreadsSupported));
            }
        }
    }

    //starting main thread simulation
    if(remainder != 0){
        generatereturns(steps, MCsize / concurentThreadsSupported + 1);
        remainder--;
    }else{
        generatereturns(steps, MCsize / concurentThreadsSupported);
    }

    for (auto& th : threads) th.join();

    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now() ;
    typedef std::chrono::duration millisecs_t ;
    millisecs_t duration( std::chrono::duration_cast(end-start) ) ;
    std::cout << "Time elapsed : " << duration.count() << " milliseconds.\n" ;

    return 0;
}

我无法理解为什么我的R代码比我的C++代码(3.29s vs 12s)快得多,即使我在C++代码中使用了四个线程?请问有人可以开导我吗?我应该如何改进我的C++代码以使其运行得更快?

编辑:

感谢所有的建议!我保留了向量的容量,减少了代码中的锁定量.generatereturns()函数中的关键更新是:

std::vector cache(MCsize);
std::vector::iterator currit = cache.begin();
//.....

// Creating generator
std::binomial_distribution distribution(steps,0.5);
std::mt19937 generator(seed_);
std::vector tmpvec(RUNS);
for(int i = 0; i!= RUNS; ++i){
    double power;
    double returns;
    power = distribution(generator);
    returns = pow(0.9,power) * pow(1.1,(double)steps - power);
    tmpvec[i] = returns;
}
std::lock_guard guard(mutex1);
std::move(tmpvec.begin(),tmpvec.end(),currit);
currit += RUNS;

我没有每次锁定,而是创建了一个临时向量,然后使用std :: move将tempvec中的元素移动到缓存中.现在经过的时间减少到1.9秒.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有