-
Notifications
You must be signed in to change notification settings - Fork 244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimizing Expand+Aggregate in sqls with many count distinct #10798
Optimizing Expand+Aggregate in sqls with many count distinct #10798
Conversation
build |
Signed-off-by: Hongbin Ma (Mahone) <mahongbin@apache.org>
d4a8261
to
cdc867d
Compare
build |
@revans2 @abellina @winningsix can you pls take a look of this PR ? we're going to pack a debug build based on this PR |
sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuExpressions.scala
Outdated
Show resolved
Hide resolved
sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuExpressions.scala
Outdated
Show resolved
Hide resolved
sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuExpressions.scala
Outdated
Show resolved
Hide resolved
sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuExpressions.scala
Outdated
Show resolved
Hide resolved
case class NullVecKey(d: DataType, n: Int) | ||
|
||
class NullVecCache(private val maxNulls: Int) | ||
extends util.LinkedHashMap[NullVecKey, GpuColumnVector](100, 0.75f, true) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't understand why we are extending a map instead of wrapping it? Or even better using some other cache data structure built for this type of use case.
If we wrapped it, then we could get true LRU functionality and be able to reset the the priority on a read. It would let us not need to override remove so it throws. That API would just not exist.
sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuExpressions.scala
Outdated
Show resolved
Hide resolved
// This is only for ExpandExec which will generate a lot of null vectors | ||
case class NullVecKey(d: DataType, n: Int) | ||
|
||
class NullVecCache(private val maxNulls: Int) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The data stored in the cache needs to be spillable in some form. Eventually it would be nice to make it so instead of spilling we can just delete the value from the cache, but in the short term we need to make sure that everything stored in the cache is spillable.
It would also be really nice to have a timeout of some kind. If an entry is unused for a specific amount of time it should be deleted to avoid adding more memory pressure to the system.
sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuExpressions.scala
Outdated
Show resolved
Hide resolved
sql-plugin/src/main/scala/com/nvidia/spark/rapids/RapidsConf.scala
Outdated
Show resolved
Hide resolved
Please retarget to 24.08 |
build |
@wjxiz1992 query perf pass |
@GaryShen2008 , I suggest to move this PR to 2410 because of the quoted reason |
Please retarget to the 24.10 branch. |
…ze_expand Signed-off-by: Hongbin Ma (Mahone) <mahongbin@apache.org>
Signed-off-by: Hongbin Ma (Mahone) <mahongbin@apache.org>
Hi @revans2 I simplified the code to make it unnecessary to worry about the side effects of global caching for null vectors. The cache reuse ratio would be smaller than previous version, but it would suffice for our customer's use case (a query with a lot of count distincts). Please help to review again |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a few nits, but I think there are still some comments from @abellina that need to be addressed
sql-plugin/src/main/scala/com/nvidia/spark/rapids/GpuExpressions.scala
Outdated
Show resolved
Hide resolved
val newColumns = boundExprs.safeMap(_.columnarEval(cb)).toArray[ColumnVector] | ||
new ColumnarBatch(newColumns, cb.numRows()) | ||
try { | ||
GpuExpressionsUtils.cachedNullVectors.get.clear() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are more ways than just this method to run a expression. I don't trust this to fix it every time. It is probably god enough in practice, but I don't like the precedence it is setting. At a minimum I want to see some comments here explaining what is happening and why. Preferably with a follow on issue to fix this once we have the ability to delete a buffer from the spill framework instead of spilling it.
Signed-off-by: Hongbin Ma (Mahone) <mahongbin@apache.org>
build |
2 similar comments
build |
build |
close #10799 |
Fixing #10799. This PR tries to optimize the Expand&Aggregate exec in the first stage of a sql with many count distinct measures.
The optimizations in this PR include: