gpt4 book ai didi

OpenCL AMD 与 NVIDIA 性能对比

转载 作者:行者123 更新时间:2023-12-02 05:02:52 24 4
gpt4 key购买 nike

我实现了一个简单的内核,它是某种卷积。我在NVIDIA GT 240上进行了测量。在CUDA上编写时需要70毫秒,在OpenCL上编写时需要100毫秒。好吧,我想,NVIDIA 编译器针对 CUDA 进行了更好的优化(或者我做错了什么)。我需要在 AMD GPU 上运行它,所以我迁移到 AMD APP SDK。完全相同的内核代码。

我做了两次测试,结果令我沮丧:HD 6670 为 200 毫秒,HD 5850 为 70 毫秒(与 GT 240 + CUDA 的时间相同)。我对这种奇怪行为的原因非常感兴趣。

所有项目均在 VS2010 上构建,分别使用 NVIDIA 和 AMD 示例项目的设置。

请不要将我的帖子视为 NVIDIA 广告。我很清楚HD 5850比GT 240更强大。我唯一想知道的是为什么会有这样的差异以及如何解决这个问题。

更新。下面是在基础图像中查找 6 个相同大小的模板图像的内核代码。基础图像的每个像素都被视为模板之一的可能来源,并由单独的线程处理。内核比较基础图像和模板图像每个像素的 R、G、B 值,如果至少有一个差异超过 diff 参数,则相应像素被视为不匹配。如果不匹配像素的数量小于 maxNonmatchQt,则命中相应的模板。

__constant int tOffset = 8196; // one template size in memory (in bytes)
__kernel void matchImage6( __global unsigned char* image, // pointer to the base image
int imgWidth, // base image width
int imgHeight, // base image height
int imgPitch, // base image pitch (in bytes)
int imgBpp, // base image bytes (!) per pixel
__constant unsigned char* templates, // pointer to the array of templates
int tWidth, // templates width (the same for all)
int tHeight, // templates height (the same for all)
int tPitch, // templates pitch (in bytes, the same for all)
int tBpp, // templates bytes (!) per pixel (the same for all)
int diff, // max allowed difference of intensity
int maxNonmatchQt, // max number of nonmatched pixels
__global int* result, // results
) {
int x0 = (int)get_global_id(0);
int y0 = (int)get_global_id(1);
if( x0 + tWidth > imgWidth || y0 + tHeight > imgHeight)
return;
int nonmatchQt[] = {0, 0, 0, 0, 0, 0};
for( int y = 0; y < tHeight; y++) {
int ind = y * tPitch;
int baseImgInd = (y0 + y) * imgPitch + x0 * imgBpp;
for( int x = 0; x < tWidth; x++) {
unsigned char c0 = image[baseImgInd];
unsigned char c1 = image[baseImgInd + 1];
unsigned char c2 = image[baseImgInd + 2];
for( int i = 0; i < 6; i++)
if( abs( c0 - templates[i * tOffset + ind]) > diff ||
abs( c1 - templates[i * tOffset + ind + 1]) > diff ||
abs( c2 - templates[i * tOffset + ind + 2]) > diff)
nonmatchQt[i]++;
ind += tBpp;
baseImgInd += imgBpp;
}
if( nonmatchQt[0] > maxNonmatchQt && nonmatchQt[1] > maxNonmatchQt && nonmatchQt[2] > maxNonmatchQt && nonmatchQt[3] > maxNonmatchQt && nonmatchQt[4] > maxNonmatchQt && nonmatchQt[5] > maxNonmatchQt)
return;
}
for( int i = 0; i < 6; i++)
if( nonmatchQt[i] < maxNonmatchQt) {
unsigned int pos = atom_inc( &result[0]) * 3;
result[pos + 1] = i;
result[pos + 2] = x0;
result[pos + 3] = y0;
}
}

内核运行配置:全局工作规模 = (1900, 1200)对于 AMD,本地工作大小 = (32, 8);对于 NVIDIA,本地工作大小 = (32, 16)。

执行时间:高清 5850 - 69 毫秒,HD 6670 - 200 毫秒,GT 240 - 100 毫秒。

任何有关我的代码的评论也非常感谢。

最佳答案

执行时间的差异是由编译器引起的。您的代码可以轻松矢量化。将图像和模板视为向量类型 char4 的数组(每个 char4 向量的第四个坐标始终为 0)。而不是 3 次内存读取:

unsigned char c0 = image[baseImgInd];
unsigned char c1 = image[baseImgInd + 1];
unsigned char c2 = image[baseImgInd + 2];

仅使用一个:

unsigned char4 c = image[baseImgInd];

如果满足以下条件,而不是笨重:

    if( abs( c0 - templates[i * tOffset + ind]) > diff || 
abs( c1 - templates[i * tOffset + ind + 1]) > diff ||
abs( c2 - templates[i * tOffset + ind + 2]) > diff)
nonmatchQt[i]++;

使用速度快:

    unsigned char4 t = templates[i * tOffset + ind];
nonmatchQt[i] += any(abs_diff(c,t)>diff);

因此,您可以将代码的性能提高多达 3 倍(如果编译器不自行对代码进行向量化)。我认为AMD OpenCL编译器没有这样的矢量化和其他优化。根据我的经验,NVIDIA GPU 上的 OpenCL 通常可以比 CUDA 更快,因为它更底层。

关于OpenCL AMD 与 NVIDIA 性能对比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8970949/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com