我一直在为我的项目使用MATLAB,我几乎从未有过使用C ++的经验。
我需要速度,我听说C ++比MATLAB更高效,更快。所以我尝试了这个:
我在MATLAB上使用rand(5000,5000)创建了一个随机数矩阵。
在C ++中,我初始化了一个为循环创建的2D向量,每个循环循环5000次并且每次都循环。 MATLAB的速度提高了4-5倍,所以我认为这是因为matlab并行执行矢量化代码,然后我使用parallel_for编写了C ++代码。这是代码:
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <fstream>
#include <ppl.h>
using namespace std;
using namespace concurrency;
int main();
{
int a = 5000, b = 5000, j, k;
vector< vector<int> > vec(a, vector<imt>(b));
parallel_for(int(0), a, [&](int i) {
for (j = 0; j <b; j++)
{
vec[i][j] = rand();
}
});
}
所以上面的代码比MATLAB rand(5000,5000)
快25%左右但是C ++使用100%的CPU,而MATLAB使用30%的CPU。
所以我强迫MATLAB使用rand(5000,5000)
运行3个MATLAB实例来使用所有CPU,并将所需时间除以3.它使MATLAB的速度是C ++的两倍。
我想知道我错过了什么?我知道这是一个很小的例子,但我需要一个答案,以确保将我的代码移植到C ++。
现状:
当我编写没有parallel_for
的C ++代码时,我获得了相同CPU使用率的一半MATLAB速度。然而,给出答案的人说他们几乎是一样的。我不明白我错过了什么
答案 0 :(得分:2)
这可能不是答案,而是一个小小的提示。
由于vectors
的使用,这种比较可能有点不公平。
这是我写的比较。两者都占据了四个可用线程中的一个的大约100%。在这两种情况下,我都会创建5000x5000
个随机数,然后执行100次计时
<强> Matlab的强>
function stackoverflow
tic
for i=1:100
A =rand(5000);
end
toc
运行时间:~27.9秒
<强> C ++ 强>
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <ctime>
using namespace std;
int main(){
int N = 5000;
double ** A = new double*[N];
for (int i=0;i<N;i++)
A[i] = new double[N];
srand(time(NULL));
clock_t start = clock();
for (int k=0;k<100;k++){
for (int i=0;i<N;i++){
for (int j=0;j<N;j++){
A[i][j] = rand();
}
}
}
cout << "T="<< (clock()-start)/(double)(CLOCKS_PER_SEC/1000)<< "ms " << endl;
}
运行时间:~28.7秒
所以这两个例子的运行速度几乎相同。
答案 1 :(得分:1)
在查看@ sonystarmap的答案后,我添加了几种类型的容器:double*
,vector<double>
和vector<vector<double> >
。我还添加了测试,其中“指针容器”是memset,因为vector
初始化所有内存。
使用这些优化标志编译C ++代码:-O3 -march=native
结果:
Matlab:经过的时间是28.457788秒。
C ++:
T = 23844.2ms
T = 25161.5ms
T = 25154ms
T = 24197.3ms
T = 24235.2ms
T = 24166.1ms
我基本上找不到你提到的巨大收益。
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <ctime>
#include <vector>
#include <cstring>
using namespace std;
int main(){
const int N = 5000;
{
vector<double> A(N*N);
srand(0);
clock_t start = clock();
for (int k=0;k<100;k++){
for (int i=0;i<N;i++){
for (int j=0;j<N;j++){
A[i*N+j] = rand();
}
}
}
cout << "T="<< (clock()-start)/(double)(CLOCKS_PER_SEC/1000)<< "ms " << endl;
}
{
vector<vector<double> > A(N);
for (int i=0;i<N;i++)
A[i] = vector<double>(N);
srand(0);
clock_t start = clock();
for (int k=0;k<100;k++){
for (int i=0;i<N;i++){
for (int j=0;j<N;j++){
A[i][j] = rand();
}
}
}
cout << "T="<< (clock()-start)/(double)(CLOCKS_PER_SEC/1000)<< "ms " << endl;
}
{
double ** A = new double*[N];
for (int i=0;i<N;i++)
A[i] = new double[N];
srand(0);
clock_t start = clock();
for (int k=0;k<100;k++){
for (int i=0;i<N;i++){
for (int j=0;j<N;j++){
A[i][j] = rand();
}
}
}
cout << "T="<< (clock()-start)/(double)(CLOCKS_PER_SEC/1000)<< "ms " << endl;
}
{
double ** A = new double*[N];
for (int i=0;i<N;i++) {
A[i] = new double[N];
memset(A[i], 0, sizeof(double) * N);
}
srand(0);
clock_t start = clock();
for (int k=0;k<100;k++){
for (int i=0;i<N;i++){
for (int j=0;j<N;j++){
A[i][j] = rand();
}
}
}
cout << "T="<< (clock()-start)/(double)(CLOCKS_PER_SEC/1000)<< "ms " << endl;
}
{
double * A = new double[N * N];
srand(0);
clock_t start = clock();
for (int k=0;k<100;k++){
for (int i=0;i<N;i++){
for (int j=0;j<N;j++){
A[i*N + j] = rand();
}
}
}
cout << "T="<< (clock()-start)/(double)(CLOCKS_PER_SEC/1000)<< "ms " << endl;
}
{
double * A = new double[N * N];
memset(A, 0, sizeof(double) * N * N);
srand(0);
clock_t start = clock();
for (int k=0;k<100;k++){
for (int i=0;i<N;i++){
for (int j=0;j<N;j++){
A[i*N + j] = rand();
}
}
}
cout << "T="<< (clock()-start)/(double)(CLOCKS_PER_SEC/1000)<< "ms " << endl;
}
}
答案 2 :(得分:1)
当您在Matlab中调用rand(5000,5000)时,Matlab通过调用Intel MKL库来执行命令,该库是用C / C ++编写的高度优化的库,带有许多手工编码的程序集。
MKL应该比任何简单的C ++实现都要快,但是Matlab调用外部库会产生开销。最终结果是,对于较小尺寸(例如小于1K)的随机数生成,纯C / C ++实现将更快,但是对于较大尺寸,Matlab将受益于超级优化的MKL。
答案 3 :(得分:0)
#include <vector>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>
int main() {
const int N = 5000;
std::vector<int> A(N*N);
srand(0);
clock_t start = clock();
for(int k = 0; k < 100; ++k){
for(int i = 0; i < N * N; ++i) {
A[i] = rand();
}
}
std::cout << (clock()-start)/(double)(CLOCKS_PER_SEC/1000) << "ms" << "\n";
return 0;
}
我的工作站上没有任何优化标志,从25-27秒到
的21秒-O3 -g -Wall -ftree-vectorizer-verbose = 5 -msse -msse2 -msse3 -march = native -mtune = native -ffast-math