Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Андрей, мы что-то воду в ступе толчем. Не хочешь окна и пикселей — возьми массив двумерный произвольного происхождения с цветами в качестве элементов. Что изменится, кроме ожидания, конечно ?
Мне в такие моменты не жлако тестовых примеров написать. Суммирование столбцов матрицы, машина у меня двухпроцессорная.
На C++ по приведенному ранее коду:
const int matrixWidth = 1280;
const int matrixHeight = 1024;
struct CHUNK
{
unsigned int *matrix;//!
int xStart, xEnd;
int nHeight;
};
unsigned* columnSum;
unsigned __stdcall ThreadFunc(void* arg)
{
CHUNK* pChunk = (CHUNK*) arg;
int xEnd = pChunk->xEnd;
int nHeight = pChunk->nHeight;
unsigned int* matrix = pChunk->matrix;//!
for (int x = pChunk->xStart; x <= xEnd; x++)
{
unsigned s = 0;
for ( int y = 0; y < nHeight; y++)
{
s += matrix[x + y * matrixWidth];//!
}
columnSum[x] = s;
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int *matrix = new unsigned int[matrixWidth*matrixHeight];//!
for(int i=0; i<matrixWidth*matrixHeight; i++)
{
matrix[i] = i;
}
int nHeight = matrixHeight;
int nWidth = matrixWidth;
columnSum = new unsigned[nWidth];
// без распараллеливания
DWORD nTime1, nTime2, dwTimeStart , dwTimeEnd;
dwTimeStart = GetTickCount();
for ( int x = 0; x < nWidth; x++)
{
unsigned s = 0;
for(int y = 0; y < nHeight; y++)
{
s += matrix[x + y * matrixWidth];//!
}
columnSum[x] = s;
}
dwTimeEnd = GetTickCount();
nTime1 = dwTimeEnd - dwTimeStart;
// а теперь распараллелим
SYSTEM_INFO si;
GetSystemInfo(&si);
unsigned nProcNumber = si.dwNumberOfProcessors;
int xChunkWidth = nWidth / nProcNumber;
CHUNK * pChunks = new CHUNK[nProcNumber];
HANDLE* hThread = new HANDLE[nProcNumber];
for ( unsigned i = 0; i < nProcNumber; i++)
{
pChunks[i].nHeight = nHeight;
pChunks[i].xStart = xChunkWidth * i;
pChunks[i].xEnd = xChunkWidth * (i + 1) - 1;
pChunks[i].matrix = matrix;//!
}
pChunks[si.dwNumberOfProcessors - 1].xEnd = nWidth - 1; // спишем на него остаток от деления
dwTimeStart = GetTickCount();
for ( unsigned i = 0; i < nProcNumber; i++)
{
hThread[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc,pChunks +i, 0, NULL);
}
WaitForMultipleObjects(nProcNumber, hThread, TRUE, INFINITE);
dwTimeEnd = GetTickCount();
nTime2 = dwTimeEnd - dwTimeStart;
std::cout << "nTime1 = " << nTime1 << " nTime2 = " << nTime2;
for ( unsigned i = 0; i < nProcNumber; i++)
CloseHandle(hThread[i]);
delete[] pChunks;
delete[] hThread;
delete[] columnSum;
delete[] matrix;
return 0;
}
Измененное выделил //!
Результаты:
nTime1 = 94 nTime2 = 94
На C# c Paralle Extension June CTP
static void Main(string[] args)
{
var matrix = new uint[1280, 1024];
var notParallel = from x in Enumerable.Range(0, matrix.GetLength(0) - 1)
select Enumerable.Range(0, matrix.GetLength(1) - 1).Sum(y => matrix[x, y]);
notParallel.ToArray(); //Чтобы выполнился JIT
var parallel = from x in Enumerable.Range(0, matrix.GetLength(0) - 1).AsParallel() //Единственное отличе от кода выше - .AsParallel
select Enumerable.Range(0, matrix.GetLength(1) - 1).Sum(y => matrix[x, y]);
parallel.ToArray(); //Чтобы выполнился JIT
var sw = new System.Diagnostics.Stopwatch();
sw.Start();
notParallel.ToArray();
sw.Stop();
var time1 = sw.ElapsedMilliseconds;
sw.Reset();
sw.Start();
parallel.ToArray();
sw.Stop();
var time2 = sw.ElapsedMilliseconds;
Console.WriteLine("time1={0} time2={1}", time1, time2);
}
Результаты немного варьируются, в среднем :
time1 = 90 time2 = 75