我和一些同龄人正在研究游戏(Rigs ofRods),并且正在尝试将OpenCL用于物理计算。同时,我们正在尝试对我们的数据结构进行一些必要的清理。我想我应该说我们正在努力清理我们的数据结构并且注意OpenCL的要求。从指针计算数组索引
使用开放式CL的问题之一是无法使用指针,因为内存空间不同。从我对OpenCL知之甚少的情况就是将所有的数据拷贝到GPU上,然后执行计算,指针值将被复制,但地址不会与期望的地址相对应。
有问题的数据集中在一个数组中,当对象需要该数据时,它们使用指向它所需对象的指针或存储数组索引。
解决OpenCL的一个解决方案是使用数组索引而不是指针。这会导致硬耦合,以后可能会导致头痛。作为一个解决方案,我有基于开始地址和当前地址计算数组索引的想法。这当然只适用于连续数组。
我写了一个示例应用程序来测试它,它工作得很好,有些人也在不同的平台上验证它。
#include <iostream>
typedef struct beam_t
{
unsigned int item;
} beam_t;
#define GLOBAL_STATIC_ASSERT(expr, msg) \
extern char STATIC_ASSERTION__##msg[1]; \
extern char STATIC_ASSERTION__##msg[(expr)?1:2]
#ifdef __amd64
typedef unsigned long pointer_int;
#else
typedef unsigned int pointer_int;
#endif
GLOBAL_STATIC_ASSERT(sizeof(pointer_int) == sizeof(pointer_int*), integer_size);
#define MAX_BEAM 5
int main()
{
beam_t beams[MAX_BEAM];
beam_t* beam_start = &beams[0];
beam_t* beam_ptr = NULL;
std::cout << "beams: " << &beams << "\n";
for(pointer_int i = 0; i < MAX_BEAM; ++i)
{
beam_ptr = &beams[i];
pointer_int diff = ((pointer_int)beam_ptr - (pointer_int)beam_start);
std::cout << "beams[" << i << "]: " << beam_ptr
<< "\t calculated index:" << diff/sizeof(beam_t)
<< "\n";
}
return 0;
}
我担心的是,这不仅仅是一个优化的解决方案。我知道这不会有任何非连续的记忆。
基本上我的问题是这样的:
在已知的连续记忆中使用这种方法会有什么缺陷?
你会如何判断它是连续的?
人们在处理这类问题时使用了什么方法?
谢谢,以及我的appologies如果格式化关闭,这是我第一次发布一个问题。
是的,我想通了这一点,我不知道该ptrdiff_t的,虽然,这样的接缝将取代pointer_int类型我在我的例子typedef定义。 我更想知道可靠性和编码实践。这是否是一种好方法,而不是一种有效的黑客/混合物。 – Apeiron 2009-09-20 19:22:28
这是惯用的方法。在C和C++中,POD数组保证是连续的。我希望CUDA和OpenCL也是如此。 – greyfade 2009-09-20 19:46:02
不仅POD,*所有*数组都保证是连续的。 – jalf 2009-09-20 20:35:26