computer-graphics-mass-spring-systems
computer-graphics-mass-spring-systems copied to clipboard
Animation is slow for sparse implementation
After switching to sparse matrices the pre-computation is significantly faster but the animation is still quite slow. If I created Q and b using multiplications and additions should they still be stored efficiently? The solve() part is what is bottlenecking the application here.
Yes, adding and multiplying sparse matrices still produces a sparse matrix.
Are you running your code in debug mode, or running the skirt example without wind? If the former is true, you shouldn't be looking at performance. If the latter is true, some other students noticed some slow behaviour as the skirt falls without wind, so it might not indicate a bug in your code - try turning on wind before running the animation, and see if this produces something like the gif in the readme.
I'm running in release mode and even the flag is still quite slow. It's pretty far from being a smooth animation.
One other problem some other students had was converting dense matrices to sparse matrices. Things like Ucur
and Uprev
are dense, and converting them to sparse matrices significantly slows things down. Eigen directly supports multiplication between dense and sparse matrices, so you don't need to do any other preprocessing to get that to work.
Thanks for the suggestions. Unfortunately, I'm not converting any dense matrices to sparse.
In case by some absurd chance someone has the same problem as me. It was because I was putting the formula that evaluates to b straight into the .solve(...) but I changed it to creating a temporary Eigen::MatrixXd variable. I'm honestly quite confused as to why this made such a huge difference but I'm guessing I had stuff in some weird format and casting it to a dense matrix did the trick.
Glad you found it.
b should dense.
The expression issue could be a known issue with Eigen. After a few days after the deadline could post it here?
On Tue, Dec 3, 2019, 11:29 PM shimismith [email protected] wrote:
In case by some absurd chance someone has the same problem as me. It was because I was putting the formula that evaluates to b straight into the .solve(...) but I changed it to creating a temporary Eigen::MatrixXd variable. I'm honestly quite confused as to why this made such a huge difference but I'm guessing I had stuff in some weird format and casting it to a dense matrix did the trick.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/alecjacobson/computer-graphics-mass-spring-systems/issues/22?email_source=notifications&email_token=AARDJGPGAEYB4LDC3ACXC5DQW4WZ5A5CNFSM4JVBFWE2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEF3WBNI#issuecomment-561471669, or unsubscribe https://github.com/notifications/unsubscribe-auth/AARDJGOYVKGIBI4QNBSUPKLQW4WZ5ANCNFSM4JVBFWEQ .
Sorry for taking a while to get back to you about this.
Initially I had,
Unext = prefactorization.solve(k*A.transpose()*d + (1/(delta_t*delta_t))*M*(2*Ucur - Uprev) + fext + 1e10*C.transpose()*C*V);and it was running very slowly.
Then I changed it to,
Eigen::MatrixXd y = k*A.transpose()*d + (1/(delta_t*delta_t))*M*(2*Ucur - Uprev) + fext + 1e10*C.transpose()*C*V; Unext = prefactorization.solve(y);
My guess is that this is caused by lazy evaluation. In Eigen, matrix expressions are only evaluated when needed. When you assign a matrix expression to a Matrix
type, it will be forced to evaluate it, but the solver takes an EigenBase
, which can be a lazy expression, so it doesn't see the need to evaluate it until the actual solve. Unfortunately, the solver's probably not caching the evaluated expression, so it's re-evaluating it any time it needs to access any of its entries.