如何解决设置内核极慢的参数OpenCL
在我的OpenCL Dijkstra算法实现中,到目前为止,最慢的部分是将一维约简图矩阵写入内核参数(即全局内存)。
我的图是一个二维数组;对于OpenCL,它被简化为一维数组,如下所示:
for (int q = 0; q < numberOfVertices; q++)
{
for (int t = 0; t < numberOfVertices; t++)
{
reducedGraph[q * numberOfVertices + t] = graph[q][t];
}
}
放入缓冲区:
cl::Buffer graphBuffer = cl::Buffer(context,CL_MEM_READ_WRITE,numberOfVertices * numberOfVertices * sizeof(int));
设置参数需要花费非常长的时间。对于我的5760万个顶点测试,将数据写入参数需要3秒钟以上,而算法本身不到1毫秒:>
kernel_dijkstra.setArg(5,graphBuffer);
内核将图形用作全局参数:
void kernel min_distance(global int* dist,global bool* verticesSet,const int sizeOfChunks,global int* result,const int huge_int,global int* graph,const int numberOfVertices)
有什么办法可以加快速度吗?谢谢!
编辑:我的内核代码:
// Kernel source,calculates minimum distance in segment and relaxes graph.
std::string kernel_code =
void kernel min_distance(global int* dist,const int numberOfVertices) {
for (int b = 0; b < numberOfVertices; b++) {
int gid = get_global_id(0);
int min = huge_int,min_index = -1;
for (int v = gid * sizeOfChunks; v < sizeOfChunks * gid + sizeOfChunks; v++) {
if (verticesSet[v] == false && dist[v] < min && dist[v] != 0) {
min = dist[v];
min_index = v;
}
}
result[gid] = min_index;
if (gid != 0) continue;
min = huge_int;
min_index = -1;
int current_min;
for (int a = 0; a < numberOfVertices; a++) {
current_min = dist[result[a]];
if (current_min < min && current_min != -1 && current_min != 0) { min = current_min; min_index = result[a]; }
}
verticesSet[min_index] = true;
// relax graph with found global min.
int a = 0;
int min_dist = dist[min_index];
int current_dist;
int compare_dist;
for (int i = min_index * numberOfVertices; i < min_index * numberOfVertices + numberOfVertices; i++) {
current_dist = dist[a];
compare_dist = graph[min_index * numberOfVertices + a];
if (current_dist > min_dist + compare_dist && !verticesSet[a] && compare_dist != 0) {
dist[a] = min_dist + compare_dist;
}
a++;
}
}
};
我如何入队:
numberOfComputeUnits = default_device.getInfo<CL_DEVICE_MAX_COMPUTE_UNITS>();
queue.enqueueNDRangeKernel(kernel_dijkstra,cl::NDRange(numberOfVertices),numberOfComputeUnits);
解决方法
这里的错误是您的内存分配太大:5.76M个顶点需要一个133TB的缓冲区,因为该缓冲区的大小是顶点数的平方。 C ++编译器和OpenCL都不会将此错误报告为错误,甚至您的内核似乎也可以正常启动和运行,但是实际上,由于内存不足,它不会计算任何内容,并且您会得到随机且不确定的结果。
通常FormControl
所花费的时间不应超过几毫秒。在开始时只进行一次初始化部分(包含缓冲区分配,this.searchField.valueChanges
.debounceTime(400)
.switchMap(term => this.searchService.search(term))
.subscribe((result) => {
this.result = result.items
});
等),然后重复运行内核或交换缓冲区中的数据而无需重新分配,这也是有益的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。