Example #1
0
/*
 * init_opencl_devices_and_shmem
 *
 * We can have performance gain using asynchronous DMA transfer when data
 * chunk it moved to OpenCL device from host machine, however, it requires
 * preparations to ensure the memory region to be copied to/from is pinned
 * on RAM; not swapped out. OpenCL provides an interface to map a certain
 * host address area as pinned buffer object, even though its size is
 * restricted to CL_DEVICE_MAX_MEM_ALLOC_SIZE parameter. Usually, it is
 * much less than size of shared memory to be assigned to PG-Strom, around
 * 500MB - 2GB in typical GPU/MIC device. So, we need to split a flat
 * continuous memory into several 'zones' to pin it using OpenCL interface.
 * Because it is a job of OpenCL intermediation server to collect properties
 * of devices, and this server shall be launched post initialization stage,
 * we also have to acquire and pin the shared memory region in the context
 * of OpenCL intermediation server, not postmaster itself.
 */
static void
init_opencl_devices_and_shmem(void)
{
    Size		zone_length = LONG_MAX;
    List	   *devList;
    ListCell   *cell;

    devList = construct_opencl_device_info(opencl_platform_index);
    if (devList == NIL)
        elog(ERROR, "PG-Strom: unavailable to use any OpenCL devices");

    foreach (cell, devList)
    {
        pgstrom_device_info	*dev_info = lfirst(cell);

        if (zone_length > dev_info->dev_max_mem_alloc_size)
            zone_length = dev_info->dev_max_mem_alloc_size;
    }
Example #2
0
/*
 * pgstrom_opencl_main
 *
 * Main routine of opencl intermediation server.
 *
 * TODO: enhancement to use multi-threaded message handler.
 */
static void
pgstrom_opencl_main(Datum main_arg)
{
	pthread_t  *threads;
	int			i;

	/* mark this process is OpenCL intermediator */
	pgstrom_i_am_clserv = true;

	/*
	 * Set up signal handlers. Currently, OpenCL Server does not pay
	 * attention on reloading of postgresql.conf, so we can ignore SIGHUP.
	 */
    pqsignal(SIGHUP, SIG_IGN);
    pqsignal(SIGTERM, pgstrom_opencl_sigterm);

    /* We're now ready to receive signals */
    BackgroundWorkerUnblockSignals();

	/* collect opencl platform/device info */
	construct_opencl_device_info();

	/* initialize opencl context and shared memory segment */
	init_opencl_context_and_shmem();
	elog(LOG, "Starting PG-Strom OpenCL Server");

	/*
	 * OK, ready to launch server thread. In the default, it creates
	 * same number with online CPUs, but user can give an explicit
	 * number using "pg_strom.opencl_num_threads" parameter.
	 *
	 * NOTE: sysconf(_SC_NPROCESSORS_ONLN) may not be portable.
	 */
	if (opencl_num_threads == 0)
		opencl_num_threads = sysconf(_SC_NPROCESSORS_ONLN);
	Assert(opencl_num_threads > 0);

	threads = malloc(sizeof(pthread_t) * opencl_num_threads);
	if (!threads)
	{
		elog(LOG, "out of memory");
		return;
	}

	for (i=0; i < opencl_num_threads; i++)
	{
		if (pthread_create(&threads[i],
						   NULL,
						   pgstrom_opencl_event_loop,
						   NULL) != 0)
			break;
	}

	/*
	 * In case of any failure during pthread_create(), worker threads
	 * will be terminated soon, then we can wait for thread joining.
	 */
	if (i < opencl_num_threads)
	{
		elog(LOG, "failed to create server threads");
		pgstrom_clserv_exit_pending = true;
		pgstrom_cancel_server_loop();
	}
	else
		elog(LOG, "PG-Strom: %d of server threads are up", opencl_num_threads);

	while (--i >= 0)
		pthread_join(threads[i], NULL);

	/* got a signal to stop background worker process */
	elog(LOG, "Stopping PG-Strom OpenCL Server");

	/*
	 * close the server queue and returns unprocessed message with error.
	 *
	 * XXX - here is possible bug if server got signals during program
	 *       building; that holds some messages and callback enqueues
	 *       the messages again.
	 */
	pgstrom_close_server_queue();
}