gpt4 book ai didi

c++ - 为什么我的 C++ 代码比 R 慢那么多?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:34:47 31 4
gpt4 key购买 nike

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

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

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

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

回复:

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 <numeric>
#include <vector>
#include <iostream>
#include <random>
#include <thread>
#include <mutex>
#include <cmath>
#include <algorithm>
#include <chrono>

const size_t MCsize = 10000000;
std::mutex mutex1;
std::mutex mutex2;
unsigned seed_;
std::vector<double> 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<int> 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<std::mutex> 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<std::thread> 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<int,std::milli> millisecs_t ;
millisecs_t duration( std::chrono::duration_cast<millisecs_t>(end-start) ) ;
std::cout << "Time elapsed : " << duration.count() << " milliseconds.\n" ;

return 0;
}

我不明白为什么我的 R 代码比我的 C++ 代码快得多(3.29 秒对 12 秒),即使我在 C++ 代码中使用了四个线程?谁能赐教吗?我应该如何改进我的 C++ 代码以使其运行得更快?

编辑:

谢谢大家的建议!我为 vector 保留了容量并减少了代码中的锁定量。 generatereturns() 函数中的关键更新是:

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

// Creating generator
std::binomial_distribution<int> distribution(steps,0.5);
std::mt19937 generator(seed_);
std::vector<double> 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<std::mutex> guard(mutex1);
std::move(tmpvec.begin(),tmpvec.end(),currit);
currit += RUNS;

我没有每次都锁定,而是创建了一个临时 vector ,然后使用 std::move 将该 tempvec 中的元素转移到缓存中。现在耗时减少到 1.9 秒。

最佳答案

首先,您是否在 Release模式下运行它?在我的笔记本电脑(Windows 7、i5 3210M)上,从调试切换到发布将运行时间从约 15 秒减少到约 4.5 秒。

此外,在我的例子中,将线程数从 4 个减少到 2 个(我只有 2 个内核,但使用超线程)进一步将运行时间减少到 ~2.4 秒。

将变量 power 更改为 int(正如 jimifiki 也建议的那样)也提供了轻微的提升,将时间减少到约 2.3 秒。

关于c++ - 为什么我的 C++ 代码比 R 慢那么多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23424036/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com