Skip to content

Instantly share code, notes, and snippets.

@harkalygergo
Created November 29, 2015 16:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save harkalygergo/be252a0487e5f480e4c2 to your computer and use it in GitHub Desktop.
Save harkalygergo/be252a0487e5f480e4c2 to your computer and use it in GitHub Desktop.
CharacterCounterOpenMP C program
/*
Function: Nagy terjedelmű, egy megánál nagyobb méretű szövegben betűk számlálása openMP és R nyelv segítségével. A szöveg csak angol karakterekből állhat. Betűk választása: 2-től 20-ig terjedően.
Version: 2015.11.29.
Copyright: Harkály Gergő | Miskolci Egyetem
Install:
- CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(CharacterCounterOpenMP C)
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR})
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} "-std=c99 -fopenmp")
SUBDIRS(src/app)
SET(CMAKE_VERBOSE_MAKEFILE on)
- src/app/CMakeLists.txt:
SET(TARGET_NAME CharacterCounterOpenMP)
LINK_DIRECTORIES(${LIBRARY_OUTPUT_PATH})
SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR})
AUX_SOURCE_DIRECTORY(. SRC)
ADD_EXECUTABLE(${TARGET_NAME} ${SRC})
TARGET_LINK_LIBRARIES(${TARGET_NAME} -lm)
- R/figure.R:
library('ggplot2')
library('reshape')
library('Cairo')
library("grid")
plottitle <- "Karakterszámlálás"
plotlabels <- c("Szekvenciális", "Automatikus párhuzamosítás", "Kontrollált párhuzamosítás")
xlabel <- "Vizsgált karakterek száma"
ylabel <- "Idő (s)"
data0 <- read.table('R/results_sequence.dat')
data1 <- read.table('R/results_simple.dat')
data2 <- read.table('R/results_controlled.dat')
d <- data.frame(data0$V2, data0$V1, data1$V1, data2$V1)
colnames(d) <- c('alpha', 'runtime1', 'runtime2', 'runtime3')
d <- melt(d, id='alpha', variable_name='series')
CairoPDF("R/results.pdf", width=30, height=12)
p<-ggplot(d,
aes_string(x=names(d)[1], y=names(d)[3], colour=names(d)[2]),
labeller=label_parsed) +
geom_point(size=4) +
geom_line(size=1.5) +
labs(title=plottitle) +
xlab(xlabel) +
ylab(ylabel) +
scale_colour_manual(values=c("black", "blue", "red", "green", "purple"), name="", labels=plotlabels, guide=guide_legend(keyheight=unit(2, "line"), keywidth=unit(5, "line"))) +
theme_gray(24) +
scale_x_continuous(breaks=round(seq(1.0, 20.0, by=1.0), 1)) +
scale_y_continuous(breaks=sort(c(round(seq(0, max(d$value)+1, by=0.5), 1)))) +
theme(legend.position="bottom")
print(p)
dev.off()
- R/results_simple.dat
- R/results_sequence.dat
- R/results_controlled.dat
Run: cmake .; make clean; make; ./bin/CharacterCounterOpenMP; Rscript R/figure.R
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>
#define NUM_THREADS 4
void main()
{
FILE *results_simple;
results_simple = fopen("R/results_simple.dat", "a");
FILE *results_sequence;
results_sequence = fopen("R/results_sequence.dat", "a");
FILE *results_controlled;
results_controlled = fopen("R/results_controlled.dat", "a");
int i, j, k, l;
double start, end, sumtime;
char *buffer, filename[100] = "text.txt";
long lSize;
FILE *fp;
fp = fopen(filename, "r");
if(!fp)
{
perror(filename);
exit(1);
}
fseek(fp, 0, SEEK_END); // set to start of the file
lSize = ftell(fp); // file's lenght
rewind(fp); // back to start of the file
buffer = calloc(1, lSize+1);
if(!buffer)
{
fclose(fp);
printf("Memóriafoglalási hiba!\n");
exit(1);
}
// read file's content
if(1!=fread(buffer, lSize, 1, fp))
{
fclose(fp);
free(buffer);
printf("Fájlbeolvasási hiba!\n");
exit(1);
}
fclose(fp);
// read characters and their count
int char_len;
do
{
printf("Megszámolni kívánt karakterek száma (2-20): ");
scanf("%d", &char_len);
} while(char_len<2 || char_len>20);
char char_list[char_len]; // stores searched characters
int char_num_list[char_len]; // stores occurrence of searched characters' count
for(i = 0; i<char_len; i++)
{
char_num_list[i] = 0;
}
for(i = 0; i<char_len; i++)
{
printf("%d: ", i+1);
scanf(" %c", &char_list[i]); // "%c" is characters with Enter, so it must be " %c"
}
// sequence
start = omp_get_wtime();
for(i=0; i<char_len; i++)
{
for(j=0; j<lSize; j++)
{
if(buffer[j] == char_list[i])
{
char_num_list[i]++;
}
}
}
end = omp_get_wtime();
sumtime = end-start;
for(i=0; i<char_len; i++)
{
printf("%c előfordulásainak a száma: %d\n", char_list[i], char_num_list[i]);
}
printf("Futási idő szekvenciálisan: %f\n", sumtime);
fprintf(results_sequence, "%f\t%d\n", sumtime, char_len);
// set null occurrence of searched characters' count
for(i=0; i<char_len; i++)
{
char_num_list[i] = 0;
}
// simple
start = omp_get_wtime();
#pragma omp parallel for num_threads(NUM_THREADS) schedule(dynamic) firstprivate(j)
for(i=0; i<char_len; i++)
{
for(j=0; j<lSize; j++)
{
if(buffer[j] == char_list[i])
{
char_num_list[i]++;
}
}
}
end = omp_get_wtime();
sumtime = end-start;
for(i=0; i<char_len; i++)
{
printf("%c előfordulásainak a száma: %d\n", char_list[i], char_num_list[i]);
}
printf("Futási idő automatikus párhuzamosítással %d szálon: %f\n", NUM_THREADS, sumtime);
fprintf(results_simple, "%f\t%d\n", sumtime, char_len);
// set null occurrence of searched characters' count
for(i=0; i<char_len; i++)
{
char_num_list[i] = 0;
}
// controlled
if(NUM_THREADS>1)
{ // egy szállal segmentation fault
long lSize_partial = lSize/NUM_THREADS; // part's lenght
long lSize_remaining = lSize-lSize_partial*NUM_THREADS; // last part's lenght
//char text_partials[NUM_THREADS-1][lSize_partial + 1]; //+1, mert a termináló karakternek is kell hely
char **text_partials = (char**)calloc(NUM_THREADS -1, sizeof(char *)); // Dinamikus helyfoglalás, enélkül nagy fájlnál seg. faulttal meghalt a program
for(i=0; i<NUM_THREADS-1; i++)
{
text_partials[i] = (char*)calloc(lSize_partial + 1,sizeof(char));
}
char text_remaining[lSize_partial + lSize_remaining + 1];
int pos = 0; // A daraboláshoz használt pozicíó változója, hogy tudjuk, honnan vágjuk le a főstringet
for(i=0; i<NUM_THREADS-1; i++)
{
strncpy(text_partials[i], buffer + pos, lSize_partial); //darabolás
text_partials[i][lSize_partial] = '\0';
pos += lSize_partial;
}
strncpy(text_remaining, buffer + pos, lSize_partial + lSize_remaining); //utolsó rész darabolása
text_remaining[lSize_partial + lSize_remaining] = '\0';
start = omp_get_wtime();
omp_set_num_threads(NUM_THREADS);
//parallel for helyett parallel region
#pragma omp parallel
{
int ID = omp_get_thread_num(), m, n, char_num_list_p[char_len];
if(ID==0)
{
if(NUM_THREADS!=omp_get_num_threads())
{
printf("Nem sikerült megfelelő számú szálat lefoglalni!\n");
exit(1);
}
}
for(m=0; m<char_len; m++)
{
char_num_list_p[m] = 0;
}
if(ID<NUM_THREADS-1)
{ //Első részek
for(n=0; n<char_len; n++)
{
for(m=0; m<lSize_partial; m++)
{
if(text_partials[ID][m] == char_list[n])
{
char_num_list_p[n] += 1;
}
}
}
}
else if(ID == NUM_THREADS-1)
{ //Utolsó részek
for(n=0; n<char_len; n++)
{
for(m=0; m<lSize_partial+lSize_remaining; m++)
{
if(text_remaining[m] == char_list[n])
{
char_num_list_p[n] += 1;
}
}
}
}
#pragma omp critical
{
for(m=0; m<char_len; m++)
{
char_num_list[m] += char_num_list_p[m];
}
}
}
end = omp_get_wtime();
sumtime = end - start;
for(i=0; i<char_len; i++)
{
printf("%c előfordulásainak a száma: %d\n", char_list[i], char_num_list[i]);
}
printf("Futási idő %d szálon: %f\n", NUM_THREADS, sumtime);
fprintf(results_controlled, "%f\t%d\n", sumtime, char_len);
for(i=0; i<NUM_THREADS-1; i++)
{
free(text_partials[i]);
}
free(text_partials);
}
fclose(results_simple);
fclose(results_sequence);
fclose(results_controlled);
free(buffer);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment