处理每个数组行有 100 到 100 条指令的大型 3d 数组是否是一个需要在 GPU 上解决的好问题?
Is processing a large 3d array with anywhere from 100 to 100 instructions per array row a good problem to be solved on the GPU?
我有一个问题,我需要 运行 大型 3d 数组上的复杂函数。对于每个数组行,我将执行 100 到 1000 条指令,并且根据该行上的数据执行或不执行某些指令。
这个数组很大,但仍适合 GPU 共享内存(大小约为 2GB)。我可以在数组的不同部分执行这些指令,因为它们不需要按顺序处理,所以我认为在 GPU 上执行可能是一个不错的选择。我不完全确定,因为执行的指令会根据数据本身而改变(里面有很多 if/then/else),而且我读过分支可能是个问题。
这些指令是一个抽象语法树,表示对数组行和 returns 值进行操作的短程序。
这看起来像是应该由 GPU 解决的适当问题吗?
还需要哪些其他信息才能确定?
我正在考虑用 Java 编写并使用 JCuda。
谢谢!
爱德华多
视情况而定。您的阵列有多大,即您的阵列提供了多少个并行任务(在您的情况下,听起来行数就是您要执行的并行任务的数量)?如果您的行(AST)很少但列(命令)很多,那么这可能不值得。反过来会更好,因为可以并行处理更多工作。
如果您没有意识到,分支确实可能是一个问题。你可以做一些优化来降低成本 - 在你得到你的初始原型 运行ning 并且可以做一些比较测量之后。
分支的问题在于,一个“块”中的所有流式多处理器都需要执行相同的指令。如果一个内核不需要该指令,它就会休眠。因此,如果您有两个 AST,每个都有 100 个不同的命令,多处理器将需要 200 个命令来完成计算,一些 SM 将在其他执行命令时休眠。
如果您最多有 1000 个命令,而有些命令仅使用一个子集,则处理器将采用与具有最多命令的 AST 一样多的命令 - 在最佳情况下。例如。一组 (100, 240, 320, 1, 990) 将 运行 用于至少 990 个命令,即使其中一个 AST 仅使用一个命令。如果该命令不在最后一个 AST 的 990 个命令集中,它甚至 运行s 对于 991 个命令。
您可以通过优化发送到 GPU 的数组来缓解这种情况(在原型工作并可以进行实际测量之后),以便一组流式多处理器(块)具有一组类似的指令来执行.由于不同的 SM 在执行层面上不会相互干扰,因此它们不需要相互等待。当您执行代码时,块的大小也是可配置的,因此您可以在此处稍微调整它。
为了进一步优化 - 一个块中只有 32(NVidia“Warp”)/64(AMD“Wavefront”)线程同时执行,所以如果你组织你的数组来利用它,你甚至还能收获更多。
这些优化产生的差异有多大取决于您的命令数组的稀疏/密集/混合程度。也不是所有的优化实际上都优化了你的执行时间。测试和比较是这里的关键。另一个优化来源是您的内存布局,但对于您描述的用例,这应该不是问题。您可以查找 Memory Coalescing 了解更多信息。
我有一个问题,我需要 运行 大型 3d 数组上的复杂函数。对于每个数组行,我将执行 100 到 1000 条指令,并且根据该行上的数据执行或不执行某些指令。
这个数组很大,但仍适合 GPU 共享内存(大小约为 2GB)。我可以在数组的不同部分执行这些指令,因为它们不需要按顺序处理,所以我认为在 GPU 上执行可能是一个不错的选择。我不完全确定,因为执行的指令会根据数据本身而改变(里面有很多 if/then/else),而且我读过分支可能是个问题。
这些指令是一个抽象语法树,表示对数组行和 returns 值进行操作的短程序。
这看起来像是应该由 GPU 解决的适当问题吗?
还需要哪些其他信息才能确定?
我正在考虑用 Java 编写并使用 JCuda。
谢谢!
爱德华多
视情况而定。您的阵列有多大,即您的阵列提供了多少个并行任务(在您的情况下,听起来行数就是您要执行的并行任务的数量)?如果您的行(AST)很少但列(命令)很多,那么这可能不值得。反过来会更好,因为可以并行处理更多工作。
如果您没有意识到,分支确实可能是一个问题。你可以做一些优化来降低成本 - 在你得到你的初始原型 运行ning 并且可以做一些比较测量之后。
分支的问题在于,一个“块”中的所有流式多处理器都需要执行相同的指令。如果一个内核不需要该指令,它就会休眠。因此,如果您有两个 AST,每个都有 100 个不同的命令,多处理器将需要 200 个命令来完成计算,一些 SM 将在其他执行命令时休眠。
如果您最多有 1000 个命令,而有些命令仅使用一个子集,则处理器将采用与具有最多命令的 AST 一样多的命令 - 在最佳情况下。例如。一组 (100, 240, 320, 1, 990) 将 运行 用于至少 990 个命令,即使其中一个 AST 仅使用一个命令。如果该命令不在最后一个 AST 的 990 个命令集中,它甚至 运行s 对于 991 个命令。
您可以通过优化发送到 GPU 的数组来缓解这种情况(在原型工作并可以进行实际测量之后),以便一组流式多处理器(块)具有一组类似的指令来执行.由于不同的 SM 在执行层面上不会相互干扰,因此它们不需要相互等待。当您执行代码时,块的大小也是可配置的,因此您可以在此处稍微调整它。
为了进一步优化 - 一个块中只有 32(NVidia“Warp”)/64(AMD“Wavefront”)线程同时执行,所以如果你组织你的数组来利用它,你甚至还能收获更多。
这些优化产生的差异有多大取决于您的命令数组的稀疏/密集/混合程度。也不是所有的优化实际上都优化了你的执行时间。测试和比较是这里的关键。另一个优化来源是您的内存布局,但对于您描述的用例,这应该不是问题。您可以查找 Memory Coalescing 了解更多信息。