sfl*_*lee 1 c++ performance matlab bsxfun
我试图将我的MATLAB代码转换为C++,我发现在以下情况下存在问题:
MATLAB
A = rand(1000,40000);
b = rand(1000,1);
tic;
ans = bsxfun(@ne,b,A);
toc
Run Code Online (Sandbox Code Playgroud)
C++
std::vector<std::vector<int> > A;
std::vector<int> b;
std::vector<int> ans(10000);
// initial A and b
const clock_t begin_time = clock();
for(int i = 0; i < 40000; ++i){
for(int j = 0; j < 1000; ++j){
if(A[i][j] != b[j])
ans[i]++;
}
}
double run_time = static_cast<double>((clock() - begin_time)) / CLOCKS_PER_SEC;
Run Code Online (Sandbox Code Playgroud)
我发现C++案例比MATLAB慢三倍.我想问一下是否有人知道如何更改C++代码,以便我可以有类似或相同的性能bsxfun?
在我搜索网络后,我找到了两种可能的方法:
但重点是我不知道该怎么做,我的意思是我不知道实施的细节.
摘要:
bsxfun?感谢@Peter,我使用选项编译,-O3然后问题"解决",我的意思是速度与MATLAB相同.
1-您以错误的顺序运行循环.在C和C++中,2D数组存储为行主,意思是A[j][i]并且A[j][i+1]在内存中彼此相邻.(按照这种方式思考:A[j]是第一个下标操作,返回对另一个向量的引用,然后再次下标[i]).
将数据保存在缓存中以进行尽可能多的操作是在现代处理器上执行的关键之一,这意味着您希望尽可能访问相邻元素.所以切换循环的顺序:
for(int j = 0; j < 1000; ++j){
for(int i = 0; i < 40000; ++i){
Run Code Online (Sandbox Code Playgroud)
2-编译器选项非常重要.确保您正在"发布"模式下构建,或者进行优化.
3-通常将二维数组存储在C++中作为一维数组,通过乘法自行进行行/列索引.也就是说,A将是一个大小为1000*40000的向量,而A[j][i]不是A[j*row_length + i].这具有更连续的内存(参见第1点),更少的动态内存分配和更好的缓存利用率的好处.