如何将CUDA生成的向量直接绑定到LibSVM的svm_node结构体?
无法直接将两个独立的连续index、value向量绑定到当前定义的svm_node二级指针结构,核心原因是内存布局不匹配。
你使用的svm_node结构体的内存布局为每个条目内index和value紧挨着连续存储,所有条目依次排列:
[条目0: index(int), value(double)] → [条目1: index(int), value(double)] → ... → [条目N: index(int), value(double)]
而你现有的两个独立向量的内存布局是所有index连续存储、所有value连续存储:
[index0, index1, ..., indexN] → [value0, value1, ..., valueN]
两种布局完全不兼容,不可能通过简单指针赋值实现绑定,必须做数据重排。
可行优化方案
方案1:修改CUDA核函数的输出格式,直接输出
struct svm_node类型的连续数组
改造成本最低,只需在核函数中将计算得到的index和value直接赋值给svm_node类型的输出数组对应位置,输出的数组内存布局完全符合svm_node的要求。后续你只需给testnode的每个一级指针赋值对应行的首地址,这个循环只做指针赋值,不涉及数据拷贝,开销可以忽略不计:// 假设gpu_svm_nodes是CUDA输出的连续svm_node数组,已经映射到主机可访问的地址空间 int row_len = no_classes * tnum + 2; for(i=0; i<sz[0] * sz[1]; i++){ testnode[i] = gpu_svm_nodes + i * row_len; }方案2:无法修改CUDA输出格式时,用CUDA核做并行数据重排
你可以写一个轻量CUDA核,将独立的index、value向量重排为svm_node格式的连续数组,全程在GPU侧完成,不需要CPU侧的for循环做数据拷贝,重排完成后再按方案1的方式给testnode赋值行指针即可。额外优化建议:你当前给
testnode每行单独malloc的方式会产生大量内存碎片,且内存不连续会降低访问效率。可以直接一次性申请所有svm_node所需的整块内存,再给testnode每行分配首地址,性能更高也更易维护。
内容的提问来源于stack exchange,提问作者Dresult
相关产品推荐
相关产品推荐

