Re[25]: Жизнь внутри метода
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 01.11.08 07:15
Оценка: 13 (1)
Здравствуйте, 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
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.