for (i=0;i<N;i++)
for (j=0;j<N;j++)
{
AA_[i*N+j]=0;
for (int k=0;k<N;k++)
AA_[i*N+j]+=A[k*N+i]*A[k*N+j];
}
Перемножение матриц (2 потока) help
Гуру, подскажите у меня есть 2 ядерный Athlon, мне необходимо перемножить матрицы большого размера... Могу я разделить на 2 ядра??? Ускорит ли это?? Если да, то как...
Я так понимаю, двухъядерный процессор работает как два процессора, т. е. позволяют исполнять два потока одновременно. В таком случае конечно же можно "раздвоить" вычисления на два потока.
Кстати, во многих случаях "размножение" на несколько потоков применяют и в одноядерных, и однопроцессорных системах, и это несколько помогает. Так что рекомендую в данном случае создать, скажем, 8-16 потоков. Скажем, первый поток пусть вычисляет 1, 9, 17 строки, второй - 2, 10, 18 и т. д. (в случае с 8 потоками). И даже синхронизация не нужна.
миллион на миллион на псевдо кластере из 15 процессоров (ос была Линукс) использовался MPI. Считалось долго... Примерно 3-4 часа.
Точно не помню(даром преподаватели...) но есть зависимость
быстродействия многопоточности от числа процессоров в кластере.
при небольшом колличестве процов наблюдается скачок а потом уже не так прогрессирует. Так что если есть возможность распараллелить
на 2 проца - лучше это делать выигрыш будет существенный.
Вот основной цикл:
Код:
Куда надо вставить ???
миллион на миллион на псевдо кластере из 15 процессоров (ос была Линукс) использовался MPI. Считалось долго... Примерно 3-4 часа.
[/QUOTE]
мда... не много для таких матриц!!!!
да, кстати... среда Visual Studio 6.0
на нечетные строки
а второй четные
так что циклов два+
анализ в каждом есть ли следующий чет/нечет столбец
на нечетные строки
а второй четные
так что циклов два+
анализ в каждом есть ли следующий чет/нечет столбец[/QUOTE]
Хм... мне идеология понятна... я не знаю как организовать новый процесс, чтобы он считал перемножение опрделенного столба на строчку....
Код:
int N=1000;
float *fA=new float[N*N]; // первая матрица
float *fB=new float[N*N]; // вторая
float *fC=new float[N*N]; //fC=fA*fB
float *fC__=new float[N*N]; // fC__=fA*fB - через потоки
unsigned int MyThread(LPVOID pParam)
{
int *ind = (int*) pParam;
int i=ind[0];
int j=ind[1];
fC__[i*N+j]=0;
for (int k=0;k<N;k++)
fC__[i*N+j]+=fA[i*N+k]*fB[k*N+j];
return 0;
}
void CThreadDlg::OnOK()
{
int i,j,k;
int NThread=100; // количество потоков
static int **ind;
CWinThread **pThread=new CWinThread*[NThread];
HANDLE *hThread=new HANDLE[NThread];
float MinA=1000,MinB=10000;
ind=new int*[NThread];
for (i=0;i<NThread;i++)
{
ind=new int[2];
}
srand( (unsigned)time( NULL ) );
// Задаю матрицы
for (i=0;i<N;i++)
{
for (j=0;j<N;j++)
{
fA[i*N+j]=fabs(rand()/(RAND_MAX+0.0)*(i-j)/(i+j+1.0));
fB[i*N+j]=fabs(rand()/(RAND_MAX+0.0)*(i-j)/(i+j+1.0));
}
}
for (i=0;i<N;i++)
{
for (j=0;j<N;j++)
{
fC[i*N+j]=0;
for (k=0;k<N;k++)
fC[i*N+j]+=fA[i*N+k]*fB[k*N+j];
}
}
for (i=0;i<N;i++)
{
for (j=0;j<N;)
{
for (k=0;k<NThread;k++)
if (j<N)
{
j++;
ind[k][0]=i;
ind[k][1]=j;
pThread[k]=AfxBeginThread(MyThread,(LPVOID)ind[k]);
}
for (k=0;k<NThread;k++)
{
hThread[k]= pThread[k]->m_hThread;
// ::WaitForSingleObject(hThread[k],INFINITE);
}
}
}
}
float *fA=new float[N*N]; // первая матрица
float *fB=new float[N*N]; // вторая
float *fC=new float[N*N]; //fC=fA*fB
float *fC__=new float[N*N]; // fC__=fA*fB - через потоки
unsigned int MyThread(LPVOID pParam)
{
int *ind = (int*) pParam;
int i=ind[0];
int j=ind[1];
fC__[i*N+j]=0;
for (int k=0;k<N;k++)
fC__[i*N+j]+=fA[i*N+k]*fB[k*N+j];
return 0;
}
void CThreadDlg::OnOK()
{
int i,j,k;
int NThread=100; // количество потоков
static int **ind;
CWinThread **pThread=new CWinThread*[NThread];
HANDLE *hThread=new HANDLE[NThread];
float MinA=1000,MinB=10000;
ind=new int*[NThread];
for (i=0;i<NThread;i++)
{
ind=new int[2];
}
srand( (unsigned)time( NULL ) );
// Задаю матрицы
for (i=0;i<N;i++)
{
for (j=0;j<N;j++)
{
fA[i*N+j]=fabs(rand()/(RAND_MAX+0.0)*(i-j)/(i+j+1.0));
fB[i*N+j]=fabs(rand()/(RAND_MAX+0.0)*(i-j)/(i+j+1.0));
}
}
for (i=0;i<N;i++)
{
for (j=0;j<N;j++)
{
fC[i*N+j]=0;
for (k=0;k<N;k++)
fC[i*N+j]+=fA[i*N+k]*fB[k*N+j];
}
}
for (i=0;i<N;i++)
{
for (j=0;j<N;)
{
for (k=0;k<NThread;k++)
if (j<N)
{
j++;
ind[k][0]=i;
ind[k][1]=j;
pThread[k]=AfxBeginThread(MyThread,(LPVOID)ind[k]);
}
for (k=0;k<NThread;k++)
{
hThread[k]= pThread[k]->m_hThread;
// ::WaitForSingleObject(hThread[k],INFINITE);
}
}
}
}
Да, кстати, возник вопрос. Как лучше (условно говоря): создать 10 потоков, каждый считает по 50 строк или 2 потока и каждый считает по 250 строк?
Да, кстати, возник вопрос. Как лучше (условно говоря): создать 10 потоков, каждый считает по 50 строк или 2 потока и каждый считает по 250 строк?[/QUOTE]
Я уже писал выше: рекомендую создавать 8-16, а если процессоров несколько - 32-64 потока. В общем, определи экспериментальным путем оптимальное количество.
Экспериментальный путь показал, что из должно быть >2 и все...
Ну, видимо, не такая уж большая матрица, чтобы ускорение чувствовалось :)