Linux, OpenMP и GCC: многопоточная программа в 5-6 раз медленнее однопоточной?

Изучаю OpenMP, пытаюсь распараллелить нейронную сеть. Но почему-то постоянно получается, что расспараллеленное приложение существенно медленнее, чем обычное. В чем может быть проблема?


Однопоточное приложение:
pastebin.com/22vp3LYU

Компиляция:
g++ -lrt -O0 main.cpp -o nnlv2


Многопоточное:
pastebin.com/w3m01QTK

Компиляция:
g++ -lrt -fopenmp -O0 main_openmp.cpp -o nnlv2_openmp



P.S. Не обращайте внимания на функцию sigmoid, я в курсе, что она должна выглядеть по другому :)
  • Вопрос задан
  • 5637 просмотров
Пригласить эксперта
Ответы на вопрос 7
edeldm
@edeldm
еще есть
cudaMemcpyToSymbol( «alpha», &alpha, 4);

бегло просмотрел — вроде верно все.
могу дать совет начинающего радиста — не крути две гайки одновременно.

т.е. попробуй сначала просто копировать на видюху и обратно и проверяй значения на совпадения.
затем многотредовое.

я делаю еще такое (поделюсь куском кода :) ):

__global__ void RunTest(unsigned long *heartbeat)
{
	unsigned long tid = blockIdx.x*blockDim.x + threadIdx.x;
	heartbeat[tid] = 1;
}

void Runkerneltest(int grids, int threads, unsigned long *heartbeat)
{
	RunTest <<<grids, threads>>> (heartbeat);
}




bool TestKernel(int grids, int threads)
{
	unsigned long* heartbeat =  new unsigned long [grids*threads];
	memset (heartbeat, 0, grids*threads*sizeof (unsigned long)); 
	void* heartbeat_device = 0;
	cudaError err;
	err = cudaMalloc ((void**)&heartbeat_device, grids*threads*sizeof (unsigned long));
	Check("cudaMalloc heartbeat_device",err);
	err = cudaMemset (heartbeat_device, 0, grids*threads*sizeof(unsigned long));
	Check("cudaMemset heartbeat_device",err);

	Runkerneltest(grids,threads,(unsigned long*)heartbeat_device);

	err = cudaThreadSynchronize();
	Check("cudaThreadSynchronize()", err);
	err = cudaMemcpy( heartbeat, heartbeat_device, grids*threads*sizeof(unsigned long), cudaMemcpyDeviceToHost );
	Check("cudaMemcpy( heartbeat, heartbeat_device)", err);

	bool error = false;
	for (int i=0; i<grids*threads; i++)
		if (heartbeat[i] != 1) 
		{
			LOG("tid %d test fails",i);
			error = true;
			break;
		}

	cudaFree (heartbeat_device);
	delete (heartbeat);
	return (error ? false : true); //если была ошибка, то false
}
Ответ написан
Lerg
@Lerg
Defold, Corona, Lua, GameDev
Используйте явные потоки. Например с помощью библиотеки pthread.
Ответ написан
@Robotex Автор вопроса
Оптимизировал код:

Однопоточная версия: pastebin.com/KAx4RmSJ
Многопоточная: pastebin.com/fbe4gZSn

Теперь многопоточная версия медленнее однопоточной всего в 2 раза (а нужно, чтобы минимум раза в 3 быстрее было). Что еще можно соптимизировать?
Ответ написан
@Robotex Автор вопроса
Здесь последние версии кода: ubuntuone.com/p/jPV/

Исходник с куда компилится так:
nvcc -lrt main_cuda.cu -o nnlv2_cuda

Все по прежнему печально. Куда мало что медленнее, так еще и считает не верно. Что я делаю не так?
Ответ написан
edeldm
@edeldm
параметры видюхи «автоматом» берутся отсюда:

cudaDeviceProp prop;
if(cudaGetDeviceProperties( & prop, i) == cudaSuccess) 
{
	LOG ("Device: %s\n",prop.name);
	LOG ( "Compute capability     : %d.%d\n", prop.major, prop.minor );
	LOG ( "Name                   : %s\n", prop.name );
	LOG ( "Total Global Memory    : %ld\n", prop.totalGlobalMem );
	LOG ( "Shared memory per block: %d\n", prop.sharedMemPerBlock );
	LOG ( "Registers per block    : %d\n", prop.regsPerBlock );
	LOG ( "Warp size              : %d\n", prop.warpSize );
	LOG ( "Max Grid               : %d\n", prop.maxGridSize[0] );
	LOG ( "Max threads per block  : %d\n", prop.maxThreadsPerBlock );
	LOG ( "Total constant memory  : %d\n", prop.totalConstMem );
...
 }
Ответ написан
Комментировать
mikhanoid
@mikhanoid
Так у вас же там стоит atomic перед k++. На каждой итерации нити будут синхронизовываться, чтобы друг за дружкой сделать k++. Естественно, оно будет сильно медленней.
Ответ написан
@Robotex Автор вопроса
А что если ускорения на двухядерной машине и не должно быть? В одном ядре обрабатывается основной цикл, в другом параллельная зона.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы