我正在使用犰狳库。我的程序部分太慢了,我需要加快速度,以下是
for(int q(0); q < Nk*Nk; q++){
for(int k(0); k < Nk*Nk; k++){
int kq = (k+q) % (Nk*Nk);
cx_mat Gx = ((Eigveck.slice(k)).t())*(Vxk.slice(k)-Vxk.slice(kq))*Eigveck.slice(kq);
cx_mat Gy = ((Eigveck.slice(k)).t())*(Vyk.slice(k)-Vyk.slice(kq))*Eigveck.slice(kq);
vec ek = Eigvalk.col(k);
vec ekq = Eigvalk.col(kq);
for(int i(0); i < Ltot; i++){
for(int j(0); j < Ltot; j++){
chi = chi + (abs(Gx(i,j))*abs(Gx(i,j))+abs(Gy(i,j))*abs(Gy(i,j)))*(1.0/(1.0+exp(ekq(j)/T))-1.0/(1.0+exp(ek(i)/T)))*((ekq(j)-ek(i))/((ekq(j)-ek(i))*(ekq(j)-ek(i))+eta*eta))/(Nk*Nk);
}
}
}
double qx = (G1(0)*floor(q/Nk)/Nk+G2(0)*(q % Nk)/Nk);
double qy = (G1(1)*floor(q/Nk)/Nk+G2(1)*(q % Nk)/Nk);
lindhard << qx << " " << qy << " " << -chi << " " << endl;
}
在此部分之前,我定义了一个巨大的矩阵,Eigvalk和巨大的立方体,Eigveck,Vxk,Vyk。
现在,在for循环中调用它们的值非常慢,需要很长时间。立方体包含特征向量和给定问题的其他数量。问题是,对于Nk = 10(非常小的Nk来测试代码),计算Nk * Nk = 100次47个特征向量需要0.1秒,并且执行显示使用它们的循环需要4.5秒。我已经检查了花费时间的部分是电话
cx_mat Gx = .....
我还试图定义矢量或巨大的cx_mat(通过矢量化矩阵)而不是cx_cube,但没有任何改变。
有更好的解决方法吗?
答案 0 :(得分:0)
我没有看到市长的错误。遍历矩阵的顺序是可以的。
我认为您的代码可以使用openmp reduction这样
并行计算for(int q(0); q < Nk*Nk; q++){
#pragma omp parallel for default(shared) reduction(+:chi)
for(int k(0); k < Nk*Nk; k++){
int kq = (k+q) % (Nk*Nk);
cx_mat Gx = ((Eigveck.slice(k)).t())*(Vxk.slice(k)-Vxk.slice(kq))*Eigveck.slice(kq);
cx_mat Gy = ((Eigveck.slice(k)).t())*(Vyk.slice(k)-Vyk.slice(kq))*Eigveck.slice(kq);
vec ek = Eigvalk.col(k);
vec ekq = Eigvalk.col(kq);
for(int i(0); i < Ltot; i++){
for(int j(0); j < Ltot; j++){
chi = chi + (abs(Gx(i,j))*abs(Gx(i,j))+abs(Gy(i,j))*abs(Gy(i,j)))*(1.0/(1.0+exp(ekq(j)/T))-1.0/(1.0+exp(ek(i)/T)))*((ekq(j)-ek(i))/((ekq(j)-ek(i))*(ekq(j)-ek(i))+eta*eta))/(Nk*Nk);
}
}
}
double qx = (G1(0)*floor(q/Nk)/Nk+G2(0)*(q % Nk)/Nk);
double qy = (G1(1)*floor(q/Nk)/Nk+G2(1)*(q % Nk)/Nk);
lindhard << qx << " " << qy << " " << -chi << " " << endl;
}
聚苯乙烯。
也许您定义了一些const局部变量,例如
const auto delta = ekq(j)-ek(i);
你是如何衡量你的热点的?
您使用哪些编译器选项?我假设您已启用适当的优化级别,对吧?