写GPU程序的时候尽量避免使用二级指针吧

前几天做实验的时候写了一段程序,测试完成后,需要把这段程序从CPU上移植到GPU上。本来想着这活不会太难,可能半天时间就搞定了吧,没想到已经花了三天多的时间了,磕磕绊绊的还没彻底结束,不过GPU的程序总算已经有个样子了,于是打算抽时间把这几天的血泪经验总结一下,那就是:不!要!使!用!二!级!指!针!!!!!

(平静一下心情~~~)

我们先从内存说起吧。每一个内存单元都包含两个属性,一个是“地址”,一个是“内容”。把内存比喻成许多抽屉组成的柜子,那一个内存单元就相当于柜子里面的小抽屉,每个小抽屉有两个属性,一个它能装东西(内容),二是它有个抽屉编号(地址)。比如下面就是一个内存的示意图,每一个小方格是一个内存单元,浅蓝是它的内容,深蓝是它的地址:

内存示意图

内存的地址是固定的,没法改变。比如上面的小方格地址表示为在第几行第几列,我们没法改变。程序猿可以控制的是内存的内容。一种特殊的情况就是,如果一个内存单元的内容是别的内存的地址,那么它就被称为指针,比如下图中,左边的内存单元就被称为指针,因为它的内容,是右边内存单元的地址。我们称这种情况为左边的指针指向了右边的内存单元。

指针

如果我们任性一点,让一个指针指向另一个指针,即所谓的螳螂捕蝉黄雀在后,那么就得到了一个二级指针,如下图所示。以此类推,我们理论上可以定义三级,四级等多级指针(不过现实中我还没见过什么地方要用到四级指针)

指针与二级指针

每一本C语言的教科书都会讲到指针,而且还会特别声明指针是有害的,尽量别用它。猜猜为什么?因为它太灵活了,指针在内存中变来变去,如果程序稍微复杂一点,那么人脑很可能就顾不过来了,说不定哪个指针就变成了被遗忘的孩子,到处惹是生非。有些高级语言已经干脆取消了指针。不过就像前面说的,指针灵活呀,有些事情用它很方便就能完成了。所以说呢,每一个程序猿需要在灵活性与安全性之间权衡取舍一番。

好,介绍完了背景知识,现在该说说我遇到的问题了。在用C++写程序的时候定义了一个类Sample,头文件是:

#include"stdio.h"

#include"InstanceList.h"

usingnamespacestd;

classSample

{

public:

Sample();

int* Data;

intAttributesCount;

intAttributesInLastInt;

intIntPerInstance;

intTrueInstanceCount;

intSize;

};

其中有一个成员变量Data,它是一个int型指针,顾名思义是用来存储数据的。由于数据很多,直接传内容特别浪费内存和时间,所以整个程序中只保留了一个备份。每次有函数需要用这些数据的时候,就传Sample的地址(也就是它的指针)。用Sample的地址读取像IntPerInstance这样的变量的时候,它就是指针,但要注意,读取Data的时候,它就变成了二级指针了。

虽然用到了二级指针,但我处理的比较小心,程序在CPU上能够正常运行,不过移植到GPU的时候,运行一下就出现了段错误(段错误的意思是,我的指针指向了程序不能够使用的内存):

段错误

为什么会这样呢?因为使用GPU的时候,程序的内存包括两部分,一部分位于CPU当中,一部分位于GPU当中,而由于CPU和GPU是两块独立的设备,他们的指针是不能指向对方的地址的,比如下图的情况,就绝对禁止。

禁止CPU和GPU之间的指针

所以,本来好好的程序,因为指针的原因,就可能发生各种段错误。说到这里,其实只说清楚了在写GPU程序的时候,“使用指针容易引发错误”,但题目里为什么强调是二级指针的问题呢?

因为在GPU当中,内存还细分为global memory和shared memory,每次用指针的时候都要确定是global还是shared类型的。虽然编译器从二级指针定义的地方,可以很方便的知道它自身是哪种类型的,不过它指向的一级指针随时都可能发生变动,很难检查出来到底是什么指针,于是编译器就要报警告了,就像下面:

警告,强制默认是global memory

所有这些报警告的地方,都是因为使用了samplepointer->Data[address]这样的语句。编译器确定samplepointer是一个global类型的指针之后,再也无力确定Data是什么类型的指针了,只好假设Data是一个global类型的指针。虽然由于别的原因,这种假设有99.99%的正确率,不过看着这么多警告,一来危险,二来着实让人不爽啊~

目前这些警告并不会影响我程序的正常运行,但后面还要加新的功能,很不方便。网上有人提到了一两种可行的解决办法,我试了没效果,于是这几天花大力气把代码结构改了,删了Sample类,用一个数组代替,整个过程还是很耗时间的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容