#c #pthreads #mutex
Вопрос:
pthread_mutex_t hotplate_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
//global array
float* oldTemp;
float* newTemp;
float* Temporary;
*/
double time1()
{
struct timeval tv;
gettimeofday( amp;tv, ( struct timezone * ) 0 );
return ( (double) (tv.tv_sec (tv.tv_usec / 1000000.0))
);
}
/* get params */
//made important arg variables global
//all of the user inputs variable names
int numRows, numCols, threads;
float topTemp, leftTemp, rightTemp, botTemp, epsilon;
/*check function for power of two*/
bool isPowerOfTwo(int n)
{
if (n == 0)
return false;
return(ceil(log2(n)) == floor(log2(n)));
}
/* calc_hotplate*/
void* calcHotPlate(void* unused )
{
int i,j;
//To print which thread is excuting
// printf("From the function, the thread id = %dn",
// pthread_self());
//usleep(1000000);
//three arrays/matrix to go back and forth between newand old
//values. filled in with 0's
float oldTemp[numRows][numCols];
memset(oldTemp, 0, sizeof(oldTemp[numRows][numCols]) * numRows * numCols);
float newTemp[numRows][numCols];
memset(newTemp, 0, sizeof(newTemp[numRows][numCols]) * numRows * numCols);
float Temporary[numRows][numCols];
memset(Temporary, 0, sizeof(Temporary[numRows][numCols]) * numRows * numCols);
//initialize rows with correct vals
//top row
//i;
for (i = 0; i < numCols; i )
{
oldTemp[0][i] = topTemp;
newTemp[0][i] = topTemp;
}
//left temp
for (i = 0; i < numRows; i )
{
oldTemp[i][0] = leftTemp;
newTemp[i][0] = leftTemp;
}
//right col
for (i = 0; i < numRows; i )
{
oldTemp[i][numCols - 1] = rightTemp;
newTemp[i][numCols - 1] = rightTemp;
}
//bottom row
for (i = 0; i < numCols; i )
{
oldTemp[numRows - 1][i] = botTemp;
newTemp[numRows - 1][i] = botTemp;
}
//calculate sum of edges
float sumofEdge = 0.000000;
//number of edge values
int numEdgeValues = 0;
//use all the values in top and bot rows
for (i = 0; i < numCols; i ) {
sumofEdge = oldTemp[0][i] oldTemp[numRows - 1][i];
numEdgeValues = 2;
}
//all values for left and right vals except corners
for (i = 1; i < numRows - 1; i ) {
sumofEdge = oldTemp[i][0] oldTemp[i][numCols - 1];
numEdgeValues = 2;
}
float interiorInitVal = sumofEdge / /*(float)*/ numEdgeValues;
int rowIndex = 1, colIndex = 1, range = 0;
float maxDiff = 0.000000;
for (rowIndex = 1; rowIndex < numRows - 1; rowIndex )
{
for (colIndex = 1; colIndex < numCols - 1; colIndex )
{
oldTemp[rowIndex][colIndex] = interiorInitVal;
}
}
float neighborSum, newValue;
float absDiff;
for (range; range < 1000000; range )
{
maxDiff = 0.000000;
pthread_mutex_lock(amp;hotplate_mutex);
for (rowIndex = 1; rowIndex < numRows - 1; rowIndex )
{
for (colIndex = 1; colIndex < numCols - 1; colIndex )
{ //add upper lower left and right
neighborSum = oldTemp[rowIndex - 1][colIndex] oldTemp[rowIndex 1][colIndex] oldTemp[rowIndex][colIndex - 1] oldTemp[rowIndex][colIndex 1];
newValue = neighborSum / 4.000000;
absDiff = fabsf(newValue - oldTemp[rowIndex][colIndex]);
if (absDiff > maxDiff)
{
maxDiff = absDiff;
}
newTemp[rowIndex][colIndex] = newValue;
}
}
//if range % 2 ==0;
if (isPowerOfTwo(range))//range = pow(2,range))
{
printf("m %.6fn", range, maxDiff);
}
memcpy(Temporary, newTemp, sizeof Temporary);
memcpy(newTemp, oldTemp, sizeof newTemp);
memcpy(oldTemp, Temporary, sizeof oldTemp);
//Temporary = newTemp;
//newTemp = oldTemp;
//oldTemp = Temporary;
if (maxDiff < epsilon)
{
printf("m %.6fn", range, maxDiff);
pthread_mutex_unlock(amp;hotplate_mutex);
break;
}
pthread_mutex_unlock(amp;hotplate_mutex);
}
}
int main(int argc, char** argv)
{
/*
//all of the user inputs variable names
int numRows, numCols, threads;
float topTemp, leftTemp, rightTemp, botTemp, epsilon;
*/
numRows = atoi(argv[1]);
numCols = atoi(argv[2]);
topTemp = atof(argv[3]);
leftTemp = atof(argv[4]);
rightTemp = atof(argv[5]);
botTemp = atof(argv[6]);
epsilon = atof(argv[7]);
threads = atoi(argv[8]);
int i;
double begin, end, time;
// threads of amount 'threads'
pthread_t td[threads];
// int range = 0;
begin = time1();
for (i = 0; i < threads; i ) { //start of thread create
pthread_create(amp;td[i], NULL, calcHotPlate, NULL);
pthread_join(td[i], NULL); //added in
}
/*
for(i=0;i<threads;i )
{
pthread_join(td[i],NULL);
}*/
end = time1();
time = end - begin;
printf("nTOTAL TIME: %fn", time);
exit(0);
}
вот как мой код печатается после запуска:
/p2 500 500 0 100 100 100 0,1 2
1 9.381264
2 5.863289
4 3.517975
8 2.024666
16 1.073090
32 0.551468
64 0.279060
128 0.140862
181 0.099609
1 9.381264
2 5.863289
4 3.517975
8 2.024666
16 1.073090
32 0.551468
64 0.279060
128 0.140862
181 0.099609
ОБЩЕЕ ВРЕМЯ: 0.127979
Комментарии:
1. Вы запускаете два потока с одинаковыми параметрами. Но не параллельно, а одно за другим. Какая в этом польза? Вы запускаете поток, а затем ждете его завершения. Вы начинаете другую нить и ждете, пока она закончится. С таким же успехом вы могли бы просто вызвать функцию.