Умножение матриц с использованием потоков Win32 - PullRequest
2 голосов
/ 20 мая 2011

Понятия не имею, что не так с моим кодом ... Он всегда возвращает нули во всех элементах. Намек на то, где проблема, было бы здорово:)

#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <ctime>
#include <windows.h>

using namespace std;

int nGlobalCount = 0;
int thread_index = 0;
int num_of_thr=5;

int a[4][4], b[4][4], c[4][4];
int i, j, k;

struct v {
    int i; /*row*/
    int j; /*column*/
};

DWORD ThreadProc (LPVOID lpdwThreadParam ) {
    //
    struct v *input = (struct v *)lpdwThreadParam;
    int avg=4*4/num_of_thr;
    int count=0;

    for(int i = 0; i <= 3 ; i++) {
        for(int j = 0; j <= 3; j++) {
            int sum=0;
            for ( k = 0 ; k <= 3; k++) {
               sum=sum+((a[input->i][k])*(b[k][input->j]));
                c[input->i][input->j]=sum;
                count++;
            }
        }
    }

    //Print Thread Number
    //printf ("Thread #: %d\n", *((int*)lpdwThreadParam));
    //Reduce the count
    return 0;
}

int main() {
    //    int x=0;
    cout<<"enter no of threads : ";
    cin>>num_of_thr;
    DWORD ThreadIds[num_of_thr];
    HANDLE ThreadHandles[num_of_thr];
    //struct v {
    //    int i; /*row*/
    //    int j; /*column*/
    //};

    struct v data[num_of_thr];
    int i , j , k;

    for ( int i = 0 ; i <= 3; i++) {
        for (int j = 0 ; j <= 3 ; j++) {
            a[i][j] = rand() % 10;
            b[i][j] = rand() % 10;
            c[i][j] = 0;
        }
    }

    for(int i = 0; i < num_of_thr/2; i++) {
        for(int j = 0; j < num_of_thr/2; j++) {
            data[thread_index].i = i;
            data[thread_index].j = j;

            ThreadHandles[thread_index] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&ThreadProc, &data[thread_index], 0,&ThreadIds[thread_index]);

            thread_index++;
        }
    }

    WaitForMultipleObjects(num_of_thr, ThreadHandles, TRUE, INFINITE);
    cout<<"The resultant matrix is "<<endl;
    for ( i = 0 ; i < 4; i++) {
        for ( j = 0 ; j < 4 ; j++)
            cout<<c[i][j]<<" ";
        cout<<endl;
    }
    for (int i=0; i<num_of_thr; i++)
        CloseHandle(ThreadHandles[i]);
    return 0;
}

Ответы [ 3 ]

2 голосов
/ 20 мая 2011

Понимаете ли вы, что у вас есть два отдельных набора переменных с именами a, b и c?Один является локальным для функции main, а другой является статическим для всей программы.Я подозреваю, что это не то, что вы хотели.Попробуйте удалить тот, который является локальным по отношению к основному.

Martyn

2 голосов
/ 20 мая 2011

Вкратце, ваше объявление суммы в цикле выглядит схематично.

for(int i = 0; i <= 3 ; i++) {
    for(int j = 0; j <= 3; j++) {
        for ( k = 0 ; k <= 3; k++)

            {
            int sum=sum+((a[input->i][k])*(b[k][input->j])); // this declaration seems wrong
            c[input->i][input->j]=sum;
            count++;
            }
        }
    }

В каждом внутреннем цикле вы повторно определяете сумму, фактически делая ее равной 0. Возможно, вы захотите переместить объявление на один или два цикла из назначения в зависимости от того, чего вы пытаетесь достичь.

1 голос
/ 20 мая 2011

Несколько вещей, которые я обнаружил во время поиска в дополнение к другим проблемам, отмеченным ранее:

  • С чем вы это компилируете? С VC ++ 2010 он «работает», так как в нем выводятся ненулевые значения, хотя он жалуется на объявление массива DWORD ThreadIds[num_of_thr]; с непостоянным размером массива (я просто сделал num_of_thr константой и закомментировал cin для проверь это быстро).
  • Вы уверены, что вводите правильное количество потоков с помощью cin >> num_of_thr; Например, если num_of_thr было 0, это объяснило бы вывод нулей. Простой cout здесь для num_of_thr был бы полезен.
  • В вашем цикле инициализации данных, начиная с for(int i = 0; i < num_of_thr/2; i++) {, вы неправильно подсчитываете потоки, что приведет к переполнению или переполнению массива. Например, если num_of_thr равно 5, то num_of_thr/2 равно 2, что приводит к инициализации только элементов 0..3, оставляя последний элемент неинициализированным. Снижение массива технически нормально, хотя последующий вызов CloseHandle() не удастся, когда он попытается освободить практически случайный дескриптор. Если вы введете большее количество потоков, вы переполните все свои массивы (попробуйте, например, num_of_thr=10).
  • Если это все еще не работает, попробуйте удалить многопоточность, чтобы увидеть, является ли причиной проблемы сам поток или код. Например, вы можете вызывать функцию ThreadProc() вручную в цикле, а не из потоков. Либо проследите через программу с помощью отладчика, либо выведите журналы в stdout / file (что также будет работать в модели потоков).
  • Вместо матрицы случайного источника я бы сначала использовал несколько фиксированных значений с известным результатом. Это облегчит определение того, действительно ли код вычисляет правильный результат.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...