OpenCL 设备的字节顺序

Endianness Of OpenCL devices

除了 gpu、cpu 和定制的 opencl 芯片之间的精度/准确性/对齐不一致之外,为什么互联网上的所有 opencl 示例都直接接受 host 端缓冲区?

clEnqueueWriteBuffer (  cl_command_queue command, ...)

__kernel void vecAdd(__global float * c, ..)
{
   int id=get_global_id(0);
   c[id]=b[id]+a[id]
}

假设 host 是小端,但设备是大端,a、b、c 是浮点数:

帮助像这样的内核:

           __kernel void nn( __global uchar *heap,__global uint * mallocCtr)
                        {
                            int id=get_global_id(0);
                            if(id==0)
                            {

                                nn_p_n * np=(nn_p_n *)malloc(heap,mallocCtr,sizeOf2(sizeof(nn_p_n)));
                                np->end=endianness_of_device();
                                np->size=sizeOf2(sizeof(nn_p_n));
                                np->id=9;
                                np->val=99.9f;

                                // lets simulate different endianness
                                np->end=1-endianness_of_device();


                                np->adr=(uint)np-(uint)heap;

                                mem_fence(CLK_GLOBAL_MEM_FENCE);
                            }

                            if(id==900)
                            {
                                // simulating another device reads buffer
                                for(int i=0;i<1000000;i++){int dummy=0; dummy++; if(dummy>id) dummy++;}

                                nn_p_n n=*((nn_p_n *)&heap[0]);
                                if(n.end!=endianness_of_device())
                                {
                                    n.size=reverseBytesInt(n.size);
                                    //if(n.size!=sizeof2(sizeof(nn_p_n)))
                                    //{  return; }
                                    n.adr=reverseBytesInt(n.adr);
                                    n.val=reverseBytesFloat(n.val);
                                }
                                nn_p_n * np=(nn_p_n *)malloc(heap,mallocCtr,sizeOf2(sizeof(nn_p_n)));
                                *np = n;
                            }

                        }

因为它目前正在使用 Intel CPU 为我的 Intel igpu 工作,而使用 Amd CPU 和 Amd GPU 的其他机器没有任何字节序问题。如果我将来在 Intel CPU 之上获得 Nvidia gpu 和 Amd gpu 怎么办?

当然,在集群计算中,需要涵盖计算机之间的字节序情况,但是虚拟 os 运行 在另一台 os 中并使用相同的设备呢?该设备是一个具有多个字节序内核的 fpga 怎么样(possible?)?

最后一个问题:OS 是否可以强制所有设备,甚至 CPU 变为相同的字节顺序?(我不这么认为,但可以由 OS 在性能 cost?)

编辑:无法os在设备端预处理只读数据。在 host 侧 those 标记为 "written" 的元素上 postprocess 是矫枉过正的,因为在整个数据中只能写入 1-2 个元素下载到 host.

可能有千兆字节

传递给内核的参数保证具有正确的字节序(因此所有类型定义 cl_int,等等),但缓冲区并非如此。这是有道理的,因为缓冲区的内容对于 OpenCL 是完全不透明的:只有用户知道如何理解里面的内容。因此,用户有责任在进行计算之前执行潜在的字节顺序转换(可能通过启动专用内核)。

换句话说:

__kernel void vecAdd(__global float * c, ..)

这里,cvalue 保证是正确的字节顺序(指针的字节本身是正确的设备顺序),但是字节 c指向的顺序是用户在主机上设置的顺序。

why all opencl examples over internet directly accept host-side buffers?

大多数程序都是在一组相当狭窄的目标平台上开发的,这些平台的特征是事先已知的:如果它们都是小端,为什么还要支持大端呢?可移植性已经是一个难题,我怀疑在一般情况下,关心字节顺序是一种显着的额外复杂性,几乎没有附加值。对于绝大多数程序来说,这根本不值得。

如果您认为这种级别的可移植性很有价值,那么实施它是您的选择。