我目前正致力于多线程mergesort计划。 我比较了多线程与单线程之间的不同运行时间。 我得到的平均值为.022279s(多)vs .00249s(单)
我的问题是为什么单线程应用程序比我的多线程更快?
与单线程相比,Isn多线程应该更有效吗?
多线程代码
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void *run(void *parameters); /* threads call this function */
int alength, flength;
int *array_whole;
FILE *input_file;
int *read_file(char *file_name) {
input_file = fopen("soulfoodinput.txt", "rt"); // open file
int arraysize = flength;
char line[80];
int integer;
int index = 0;
int *input = malloc(arraysize * sizeof(int));
while (fgets(line, 80, input_file) != NULL)
{
sscanf(line, "%d", &integer); // read the integer value
input[index] = integer;
//printf(line);
++index;
++alength;
}
fclose(input_file); // close the file
return input;
}
int read_length(char *file_name) {
input_file = fopen(file_name, "rt"); // open file
char line[80];
int file_length = 0;
while (fgets(line, 80, input_file) != NULL) {
file_length += 1;
}
return file_length;
}
void merge(int arr[], int left, int middle, int right) //function to sort unsorted array
{
int i, j, k;
//create array partition
int left_partition = middle - left + 1;
int right_partition = right - middle;
int first[left_partition], second[right_partition]; //set up temporary arrays
//move left side of array to temp array
for (i = 0; i < left_partition; i++)
{
first[i] = arr[left + i];
}
//move right side of array to temp array
for (j = 0; j < right_partition; j++)
{
second[j] = arr[middle + 1 + j];
}
i = 0;
j = 0;
k = left;
while (i < left_partition && j < right_partition)
{
//sort the array into one array
if (first[i] <= second[j])
{
arr[k] = first[i];
++i;
}
else
{
arr[k] = second[j];
j++;
}
k++;
}
while (i < left_partition)
{
arr[k] = first[i];
i++;
k++;
}
while (j < right_partition)
{
arr[k] = second[j];
j++;
k++;
}
}
void merge_sort(int arr[], int left, int right) //splits array in half, calls self on both halves, then merges the halves
{
if (left < right)
{
int middle = (left + (right-1))/ 2;
merge_sort(arr, left, middle); //split left half
merge_sort(arr, middle+1, right); //split right half
merge(arr, left, middle, right); //merge both halves
}
}
int main(int argc, char *argv[])
{
/*WILL CREATES THREAD ID 1, 2, 3 */
pthread_t thread_id1; // creates first thread id
pthread_attr_t attr_1; // creates thread attributes
pthread_t thread_id2; // creates second thread id
pthread_attr_t attr_2; // second thread attributes
pthread_t thread_id3; // creates third thread id
pthread_attr_t attr_3;// third thread attributes
/* WILL READ IN FILE WITH UNSORTED ARRAY*/
char *file_name = argv[1];
flength = read_length(file_name);
array_whole = read_file(file_name);
clock_t t;
int m;
printf("UNSORTED: ");
for (m = 0; m < alength; m++) {
if (m == alength - 1) {
printf("%d \n", array_whole[m]);
}
else {
printf("%d, ", array_whole[m]);
}
}
t=clock();
/*WILL CREATE THREAD 1,2,3 */
char *thread_1 = "first"; // creates first thread
pthread_attr_init(&attr_1); //finds attributes
pthread_create(&thread_id1, &attr_1, run, thread_1); // create 1st thread
char *thread_2 = "second";
pthread_attr_init(&attr_2);
pthread_create(&thread_id2, &attr_2, run, thread_2); // create 2nd thread
char *thread_3 = "third";
pthread_attr_init(&attr_3);
pthread_create(&thread_id3, &attr_2, run, thread_3); // create 3rd thread
/*WILL JOIN ALL THE THREADS TOGETHER*/
pthread_join(thread_id1, NULL);
pthread_join(thread_id2, NULL);
pthread_join(thread_id3, NULL);
t=clock() - t;
double time_taken = ((double)t)/CLOCKS_PER_SEC;
/* WILL PRINT ALL SORTED VALUES */
int i;
printf("SORTED: ");
for (i = 0; i < alength; i++) {
if (i == alength - 1) {
printf("%d \n", array_whole[i]);
}
else {
printf("%d, ", array_whole[i]);
}
}
printf("elapsed time = %f seconds to execute \n", time_taken);
pthread_exit(0);
return 0;
}
void *run(void *parameters)
{
int centerspot = alength / 2;
if (strcmp(parameters, "first") == 0) {
merge_sort(array_whole, 0, centerspot);
}
if (strcmp(parameters, "second") == 0) {
merge_sort(array_whole, centerspot + 1, alength - 1);
}
if (strcmp(parameters, "third") == 0) {
merge_sort(array_whole, 0, alength - 1);
}
pthread_exit(0);
}
单线程代码
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void *run(void *parameters); /* threads call this function */
int alength, flength;
int *array_whole;
FILE *input_file;
int *read_file(char *file_name) {
input_file = fopen("soulfoodinput.txt", "rt"); // open file
int arraysize = flength;
char line[80];
int integer;
int index = 0;
int *input = malloc(arraysize * sizeof(int));
while (fgets(line, 80, input_file) != NULL)
{
sscanf(line, "%d", &integer); // read the integer value
input[index] = integer;
//printf(line);
++index;
++alength;
}
fclose(input_file); // close the file
return input;
}
int read_length(char *file_name) {
input_file = fopen(file_name, "rt"); // open file
char line[80];
int file_length = 0;
while (fgets(line, 80, input_file) != NULL) {
file_length += 1;
}
return file_length;
}
void merge(int arr[], int left, int middle, int right) //function to sort unsorted array
{
int i, j, k;
//create array partition
int left_partition = middle - left + 1;
int right_partition = right - middle;
int first[left_partition], second[right_partition]; //set up temporary arrays
//move left side of array to temp array
for (i = 0; i < left_partition; i++)
{
first[i] = arr[left + i];
}
//move right side of array to temp array
for (j = 0; j < right_partition; j++)
{
second[j] = arr[middle + 1 + j];
}
i = 0;
j = 0;
k = left;
while (i < left_partition && j < right_partition)
{
//sort the array into one array
if (first[i] <= second[j])
{
arr[k] = first[i];
++i;
}
else
{
arr[k] = second[j];
j++;
}
k++;
}
while (i < left_partition)
{
arr[k] = first[i];
i++;
k++;
}
while (j < right_partition)
{
arr[k] = second[j];
j++;
k++;
}
}
void merge_sort(int arr[], int left, int right) //splits array in half, calls self on both halves, then merges the halves
{
if (left < right)
{
int middle = (left + (right-1))/ 2;
merge_sort(arr, left, middle); //split left half
merge_sort(arr, middle+1, right); //split right half
merge(arr, left, middle, right); //merge both halves
}
}
int main(int argc, char *argv[])
{
/*WILL CREATES THREAD ID */
pthread_t thread_id1; // creates first thread id
pthread_attr_t attr_1; // creates thread attributes
/* WILL READ IN FILE WITH UNSORTED ARRAY*/
char *file_name = argv[1];
flength = read_length(file_name);
array_whole = read_file(file_name);
clock_t t;
int m;
printf("UNSORTED: ");
for (m = 0; m < alength; m++) {
if (m == alength - 1) {
printf("%d \n", array_whole[m]);
}
else {
printf("%d, ", array_whole[m]);
}
}
t=clock();
/*WILL CREATE THREAD 1,2,3 */
char *thread_1 = "first"; // creates first thread
pthread_attr_init(&attr_1); //finds attributes
pthread_create(&thread_id1, &attr_1, run, thread_1); // create 1st thread
/*WILL JOIN ALL THE THREADS TOGETHER*/
pthread_join(thread_id1, NULL);
t=clock() - t;
double time_taken = ((double)t)/CLOCKS_PER_SEC;
/* WILL PRINT ALL SORTED VALUES */
int i;
printf("SORTED: ");
for (i = 0; i < alength; i++) {
if (i == alength - 1) {
printf("%d \n", array_whole[i]);
}
else {
printf("%d, ", array_whole[i]);
}
}
printf("elapsed time = %f seconds to execute \n", time_taken);
pthread_exit(0);
return 0;
}
void *run(void *parameters)
{
int centerspot = alength / 2;
merge_sort(array_whole, 0, centerspot);
merge_sort(array_whole, centerspot + 1, alength - 1);
merge_sort(array_whole, 0, alength - 1);
pthread_exit(0);
}
答案 0 :(得分:2)
多线程的性能可以用大量数据来衡量。使用非常少量的数据,您无法测量多线程应用程序的性能。原因: -
1.要创建一个线程O / S需要为每个线程分配内存需要花费时间(即使它很小)。
2.当您创建多线程时,它需要上下文切换,这也需要时间。
3.需要释放分配给线程的内存,这也需要时间。
4.取决于您机器中的处理器数量和总内存(RAM)
因此,当您尝试使用多线程进行小操作时,其性能将与单线程相同甚至更低。所以在这种情况下你的结果是完美的。要测量多线程架构的性能,请使用大量数据并进行复杂操作,然后才能看到差异。
答案 1 :(得分:1)
线程需要时间来设置和启动。要完成的工作量越大,多线程减少完成任务所花费的总时间的可能性就越大。
在你的例子中,我猜测文件 soulfoodinput.txt 不是很大,所以我建议把它放大,如果可能的话它应该包含数百甚至数千行。然后看看多线程代码是否比单线程运行得快。