我在OpenCL上工作,我只有一个CPU i3核心Duo =>我只拥有1个设备(我的CPU)。所以基本上,我猜我的HOST(CPU)也将是DEVICE。我尝试启动内核,但分配给DEVICE(也是HOST)的任务永远不会终止。在考虑这个问题后,似乎显而易见的是,等待DEVICE(本身)完成的HOST是不可能的。但是有没有人知道解决这个问题的方法?也许使用clCreateSubDevice,将我的唯一设备细分为主机和真实设备?使用主机作为设备
使用主机作为设备
回答
我觉得我的想法并没有那么糟糕,因为的确需要以编程方式强制HOST切换到DEVICE工作,在这种情况下,HOST和DEVICE都是相同的硬件。实际上,可以将HOST作为DEVICE,但为了让DEVICE工作,至少需要调用一个阻塞函数(clFinish()或clEnqueueRead(... CL_TRUE,...))。 ..))。否则,主机将始终工作,并永远不会切换到DEVICE工作。我尝试添加一个sleep()函数,但它不起作用,您确实需要添加一个阻塞的opencl函数。
非常感谢!
这不是真的,入队函数没有阻塞。例如,'clEnqueueNDRangeKernel'函数只是将内核放入一个队列中。即使内核尚未完成,主机线程也会继续执行。 –
谢谢你,马丁,但请在我之前的回复之前查看我的代码,以便让我知道我的错误。在clFinish(...)指令被注释的情况下,我检索任务INCOMPLETE作为输出,并且任务COMPLETE事例clFinish(...)被分解。你能说我为什么,我的错误在哪里?谢谢 – Algernon2
是的,'clFinsh'等待命令完成并因此阻塞主机线程。但是,'clEnqueueNDRangeKernel'仍然是非阻塞的。你可以在两次通话之间做任何你想要的东西。 –
您会在下面找到我的类似java的代码,以便让我知道我的错误。其实当我运行下面的代码没有clFinish(commandQueue); (在底部代码),我有以下输出:
我使用平台英特尔(R)OpenCL 入队内核... 暂停15000毫秒。 任务未完成
如果我添加clFinish(commandQueue)我有输出,我的任务完成:
我使用该平台的英特尔(R)OpenCL的 内核进行排队... 事件内核状态:CL_COMPLETE事件ID:10运行时间:2.631ms 暂停15000毫秒。 任务完成
那么为什么单个clFinish()指令允许我完成任务?感谢您提前解释。
public class Test_CPU
{
private static String programSource0 =
"__kernel void vectorAdd(" +
" __global const float *a,"+
" __global const float *b, " +
" __global float *c)"+
"{"+
" int gid = get_global_id(0);"+
" c[gid] = a[gid]+b[gid];"+
"}";
/**
* The entry point of this sample
*
* @param args Not used
*/
public static void main(String args[])
{
/**
* Callback function that is called when the event ev has the event_status status and will display the runtime of execution kernel in seconds
* @param event: the event
* @param event_status: status of the event
* @param user_data: data given by the user is an integer tag that can be used to match profiling output to the associated kernel
* @return: none
*/
EventCallbackFunction kernelCommandEvent = new EventCallbackFunction()
{
@Override
public void function(cl_event event, int event_status, Object user_data)
{
int evID = (int)user_data;
long[] ev_start_time = new long[1];
Arrays.fill(ev_start_time, 0);
long[] ev_end_time = new long[1];
Arrays.fill(ev_end_time, 0);
long[] return_bytes = new long[1];
double run_time = 0.0;
clGetEventProfilingInfo (event, CL_PROFILING_COMMAND_QUEUED, Sizeof.cl_long, Pointer.to(ev_start_time), return_bytes);
clGetEventProfilingInfo (event, CL_PROFILING_COMMAND_END , Sizeof.cl_long, Pointer.to(ev_end_time), return_bytes);
run_time = (double)(ev_end_time[0] - ev_start_time[0]);
System.out.println("Event kernel status: " + CL.stringFor_command_execution_status(event_status) + " event ID: " + evID + " runtime: " + String.format("%8.3f", (run_time*1.0e-6)) + " ms.");
}
};
// Initialize the input data
int n = 1000000;
float srcArrayA[] = new float[n];
float srcArrayB[] = new float[n];
float dstArray0[] = new float[n];
for (int i=0; i<srcArrayA.length; i++)
{
srcArrayA[i] = i;
srcArrayB[i] = i;
}
Pointer srcA = Pointer.to(srcArrayA);
Pointer srcB = Pointer.to(srcArrayB);
Pointer dst0 = Pointer.to(dstArray0);
// The platform, device type and device number that will be used
final int platformIndex = 1;
final long deviceType = CL_DEVICE_TYPE_CPU;
final int deviceIndex = 0;
// Enable exceptions and subsequently omit error checks in this sample
CL.setExceptionsEnabled(true);
// Obtain the number of platforms
int numPlatformsArray[] = new int[1];
clGetPlatformIDs(0, null, numPlatformsArray);
int numPlatforms = numPlatformsArray[0];
// Obtain a platform ID
cl_platform_id platforms[] = new cl_platform_id[numPlatforms];
clGetPlatformIDs(platforms.length, platforms, null);
cl_platform_id platform = platforms[platformIndex];
long size[] = new long[1];
clGetPlatformInfo(platform, CL_PLATFORM_NAME, 0, null, size);
// Create a buffer of the appropriate size and fill it with the info
byte buffer[] = new byte[(int)size[0]];
clGetPlatformInfo(platform, CL_PLATFORM_NAME, buffer.length, Pointer.to(buffer), null);
// Create a string from the buffer (excluding the trailing \0 byte)
System.out.println("I use the platform " + new String(buffer, 0, buffer.length-1));
// Initialize the context properties
cl_context_properties contextProperties = new cl_context_properties();
contextProperties.addProperty(CL_CONTEXT_PLATFORM, platform);
// Obtain the number of devices for the platform
int numDevicesArray[] = new int[1];
clGetDeviceIDs(platform, deviceType, 0, null, numDevicesArray);
int numDevices = numDevicesArray[0];
// Obtain a device ID
cl_device_id devices[] = new cl_device_id[numDevices];
clGetDeviceIDs(platform, deviceType, numDevices, devices, null);
cl_device_id device = devices[deviceIndex];
// Create a context for the selected device
cl_context context = clCreateContext(contextProperties, 1, new cl_device_id[]{device}, null, null, null);
// Create a command-queue, with profiling info enabled
long properties = 0;
properties |= CL.CL_QUEUE_PROFILING_ENABLE;
cl_command_queue commandQueue = CL.clCreateCommandQueue(context, devices[0], properties, null);
// Allocate the buffer memory objects
cl_mem srcMemA = CL.clCreateBuffer(context, CL.CL_MEM_READ_ONLY | CL.CL_MEM_COPY_HOST_PTR, Sizeof.cl_float * n, srcA, null);
cl_mem srcMemB = CL.clCreateBuffer(context, CL.CL_MEM_READ_ONLY | CL.CL_MEM_COPY_HOST_PTR, Sizeof.cl_float * n, srcB, null);
cl_mem dstMem0 = CL.clCreateBuffer(context, CL.CL_MEM_READ_WRITE, Sizeof.cl_float * n, null, null);
// Create and build the the programs and the kernels
cl_program program0 = CL.clCreateProgramWithSource(context, 1, new String[]{ programSource0 }, null, null);
// Build the programs
CL.clBuildProgram(program0, 0, null, null, null, null);
// Create the kernels
cl_kernel kernel0 = CL.clCreateKernel(program0, "vectorAdd", null);
// Set the arguments
CL.clSetKernelArg(kernel0, 0, Sizeof.cl_mem, Pointer.to(srcMemA));
CL.clSetKernelArg(kernel0, 1, Sizeof.cl_mem, Pointer.to(srcMemB));
CL.clSetKernelArg(kernel0, 2, Sizeof.cl_mem, Pointer.to(dstMem0));
// Set work-item dimensions and execute the kernels
long globalWorkSize[] = new long[]{n};
System.out.println("Enqueueing kernels...");
cl_event[] myEventID = new cl_event[1];
myEventID[0] = new cl_event();
clEnqueueNDRangeKernel(commandQueue, kernel0, 1, null, globalWorkSize, null, 0, null, myEventID[0]);
int ID[] = new int[1];
ID[0] = 10;
clSetEventCallback(myEventID[0], CL_COMPLETE, kernelCommandEvent, ID[0]);
clFinish(commandQueue);
System.out.println("Pause for 15000 ms.");
try
{
Thread.sleep(15000);
}
catch(InterruptedException iEx)
{
iEx.printStackTrace();
}
// See if task completed
int[] ok = new int[1];
Arrays.fill(ok, 0);
clGetEventInfo(myEventID[0], CL_EVENT_COMMAND_EXECUTION_STATUS, Sizeof.cl_int, Pointer.to(ok), null);
if (ok[0] == CL_COMPLETE) System.out.println("Task COMPLETE");else System.out.println("Task INCOMPLETE");
}
}
- 1. cudaMemcpy结构设备主机不工作
- 2. CPU作为主机,intel HD 4000作为设备1,离散gpu作为设备2在opencl
- 3. 作为专用设备的Android手机
- 4. 作为主设备的“Freemodbus”协议
- 5. 在设备代码中使用指向设备内存的主机类成员
- 6. 将数据从设备复制到主机不起作用
- 7. 使用手机作为接入点的设备的IP地址
- 8. 使用Android设备作为emualator
- 9. 从设备写入主机并通知主机
- 10. USB设备可以告诉主机启动时使用哪个备用接口?
- 11. 使用NVIDIA Quadro M4000降低主机 - 设备传输速率
- 12. CUDA主机和使用相同的设备__constant__内存
- 13. CUDA使用cudaMemcpy2D将数组从设备复制到主机
- 14. 如何使用设备访问本地主机的部分
- 15. cudaMemcpy设备到远程主机
- 16. 推力copy_if设备到主机
- 17. Android:Linux如何与主机设备交互?
- 18. CUDA主机到设备(或设备到主机)在同一块图形卡上使用OpenGL应用程序呈现图形的memcpy操作
- 19. 为什么这不是从设备复制到Cuda主机?
- 20. CUDA主机到设备的传输速度比设备到主机的传输速度更快
- 21. 当设备到主机'cudaMemcpy'时,我是否必须设置适当的设备?
- 22. 有没有办法配置xorg使用framebuffer设备作为主监视器?
- 23. 使用主机名的Apache虚拟主机设置
- 24. 将主机分支重新分配到主设备上
- 25. 为Spring RestTemplate设置“主机”标题不起作用
- 26. WP7设备上设备的主音量
- 27. sed:替换主机文件中的ip,使用主机名作为模式
- 28. Google地图不能在我的手机上作为虚拟设备使用
- 29. 我们可以使用Android手机作为谷歌家庭设备
- 30. 使用android设备作为使用热点的服务器
没有任何代码很难说,但通常你应该能够使用CPU作为设备,没有任何特殊的“箍”。 – Aderstedt
有没有这样的事情作为一个i3核心二重奏,有英特尔酷睿i3双核心,并有英特尔酷睿双核处理器。请更具体地说明您正在使用哪个CPU。我也认为你的代码可能有不同的问题。许多Core i3还包含GPU,主机和设备则使用芯片的不同部分。即使您将CPU用作设备,代码也会在单独的线程中运行。 –
无论实际的CPU和内核数量如何,大多数OpenCL CPU驱动程序都为DEVICE工作使用线程,因此HOST线程可以在计算和其他设备活动继续进行时继续执行其操作。您不需要调用阻塞API来发生工作。 – Dithermaster