I think I asked something about this long ago, but I thought it might be useful to ask now that CUDA Fortran is here.
Namely, what is the best way to handle exponentiation in CUDA Fortran? I’m currently trying to transform an old F77 code into CUDA Fortran, and so I’m encountering many of those tricks you see in hand-optimized code. For example, in my code, a variable is raised to the 58th power by:
yy=x*x
yy1=yy*yy
yy1=yy1*yy1
yy2=yy1*yy1
yy3=yy2*yy2
y=yy*yy1*yy2*yy3
which uses 8 multiplies instead of a pow operation, which is probably a faster route than
y=x**58
when you are using a CPU. But, I began to wonder if, with CUDA, I’d be better off using the ** operator? First, perhaps the __powf call that might be used (if fastmath maps ** onto that, not sure) might execute in less cycles? Or, perhaps, that the reduced register pressure might be good in a sprawling code like mine (I use maxregcount so all extra registers go to global memory)?
I ask mainly because there are many hand-coded **8, **6, and even a **58 and a **21 in this program. True, the best answer is try both out and benchmark, but at the moment this code won’t compile with -Mcuda due to too much local memory use (I’m working on cutting that down) and some weird issue with constant memory that might need a bug report (the constant struct has hundreds, thousands of entries…which isn’t right).
Matt
PS: Actually, I slightly lied. The **21 I mention above? It looks like it must be done the multiply route. Turns out the compiler gives equal results whether I use **58 or the multiplies above, but **21 is done differently than the multiply method in the current code, leading to floating-point differences.