Skip to content

Instantly share code, notes, and snippets.

@Magicdream
Created June 21, 2011 18:25
Show Gist options
  • Save Magicdream/1038511 to your computer and use it in GitHub Desktop.
Save Magicdream/1038511 to your computer and use it in GitHub Desktop.
Cilk and OpenMP version of scene detection algorithm
#include <math.h>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <sys/time.h>
#include <sys/types.h>
#include <cilk/cilk.h>
#include <cilk/reducer_opadd.h>
#define PIXEL_SIZE 3
using namespace std;
// this is just a stub
unsigned char* generateVideo(int numberOfFrames, int frameWidth, int frameHeight) {
unsigned int sizeOfFrame = frameWidth * frameHeight * PIXEL_SIZE;
unsigned char* video = new unsigned char[sizeOfFrame * numberOfFrames];
for (unsigned int i = 0; i < numberOfFrames; i++) {
for (int j = 0; j < sizeOfFrame; j++) {
video[i * sizeOfFrame + j] = i % 256;
}
}
return video;
}
void foo() {
sleep(3);
}
void prepareTest(int argc, char *argv[]) {
cilk_spawn foo();
cout << "Intel Cilk Plus version of video scene extraction algorithm" << endl;
cout << "Number of workers: " << __cilkrts_get_nworkers() << endl;
}
void computeMAFDs(unsigned char* video, int numberOfFrames, int width, int height, float* MAFDs) {
int frameSize = width * height;
int pixelsCount = frameSize * PIXEL_SIZE;
cilk_for(unsigned int k = 1; k < numberOfFrames; k++) {
unsigned char* frame1 = video + (k - 1) * pixelsCount;
unsigned char* frame2 = frame1 + pixelsCount;
cilk::reducer_opadd<float> MAFD;
MAFD.set_value(0.0);
cilk_for (int i = 0; i < pixelsCount; i += PIXEL_SIZE) {
float blue = frame1[i] - frame2[i];
float green = frame1[i + 1] - frame2[i + 1];
float red = frame1[i + 2] - frame2[i + 2];
MAFD += sqrt(blue * blue + green * green + red * red);
}
MAFDs[k - 1] = MAFD.get_value() / frameSize;
}
}
int main(int argc, char *argv[]) {
int numberOfFrames;
int width;
int height;
if (argc != 4) {
numberOfFrames = 250;
width = 720;
height = 480;
} else {
numberOfFrames = std::atoi(argv[1]);
width = std::atoi(argv[2]);
height = std::atoi(argv[3]);
}
if (numberOfFrames <= 0 || width <= 0 || height <= 0) {
cout << "Incorrect parameters used" << endl;
return 1;
}
cout << "Number of frames: " << numberOfFrames << ", width: " << width << ", height: " << height << endl;
float* MAFDs = new float[numberOfFrames - 1];
for (int i = 0; i < numberOfFrames - 1; i++) {
MAFDs[i] = 0;
}
unsigned char* video = generateVideo(numberOfFrames, width, height);
prepareTest(argc, argv);
cout << "start " << endl;
struct timeval tp;
double sec, usec, start, end;
gettimeofday( &tp, NULL );
sec = static_cast<double>( tp.tv_sec );
usec = static_cast<double>( tp.tv_usec )/1E6;
start = sec + usec;
computeMAFDs(video, numberOfFrames, width, height, MAFDs);
gettimeofday( &tp, NULL );
sec = static_cast<double>( tp.tv_sec );
usec = static_cast<double>( tp.tv_usec )/1E6;
end = sec + usec;
double time = end - start;
cout << "Time " << time << "s" << endl;
delete[] video;
delete[] MAFDs;
return 0;
}
#include <math.h>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <sys/time.h>
#include <sys/types.h>
#include <omp.h>
#define PIXEL_SIZE 3
using namespace std;
// this is just a stub
unsigned char* generateVideo(int numberOfFrames, int frameWidth, int frameHeight) {
unsigned int sizeOfFrame = frameWidth * frameHeight * PIXEL_SIZE;
unsigned char* video = new unsigned char[sizeOfFrame * numberOfFrames];
for (unsigned int i = 0; i < numberOfFrames; i++) {
for (int j = 0; j < sizeOfFrame; j++) {
video[i * sizeOfFrame + j] = i % 256;
}
}
return video;
}
void prepareTest(int argc, char *argv[]) {
out << "OpenMP version of video scene extraction algorithm" << endl;
}
void computeMAFDs(unsigned char* video, int numberOfFrames, int width, int height, float* MAFDs) {
int frameSize = width * height;
int pixelsCount = frameSize * PIXEL_SIZE;
#pragma omp parallel for
for (int k = 1; k < numberOfFrames; k++) {
unsigned char* frame1 = video + (k - 1) * pixelsCount;
unsigned char* frame2 = frame1 + pixelsCount;
float MAFD = 0.0;
// this is commented because nested parallelism is not efficient in OpenMP
//#pragma omp parallel for reduction(+:MAFD)
for (int i = 0; i < pixelsCount; i += PIXEL_SIZE) {
float blue = frame1[i] - frame2[i];
float green = frame1[i + 1] - frame2[i + 1];
float red = frame1[i + 2] - frame2[i + 2];
MAFD += sqrt(blue * blue + green * green + red * red);
}
MAFDs[k - 1] = MAFD / frameSize;
}
}
int main(int argc, char *argv[]) {
int numberOfFrames;
int width;
int height;
if (argc != 4) {
numberOfFrames = 250;
width = 720;
height = 480;
} else {
numberOfFrames = std::atoi(argv[1]);
width = std::atoi(argv[2]);
height = std::atoi(argv[3]);
}
if (numberOfFrames <= 0 || width <= 0 || height <= 0) {
cout << "Incorrect parameters used" << endl;
return 1;
}
cout << "Number of frames: " << numberOfFrames << ", width: " << width << ", height: " << height << endl;
float* MAFDs = new float[numberOfFrames - 1];
for (int i = 0; i < numberOfFrames - 1; i++) {
MAFDs[i] = 0;
}
unsigned char* video = generateVideo(numberOfFrames, width, height);
prepareTest(argc, argv);
cout << "start " << endl;
struct timeval tp;
double sec, usec, start, end;
gettimeofday( &tp, NULL );
sec = static_cast<double>( tp.tv_sec );
usec = static_cast<double>( tp.tv_usec )/1E6;
start = sec + usec;
computeMAFDs(video, numberOfFrames, width, height, MAFDs);
gettimeofday( &tp, NULL );
sec = static_cast<double>( tp.tv_sec );
usec = static_cast<double>( tp.tv_usec )/1E6;
end = sec + usec;
double time = end - start;
cout << "Time " << time << "s" << endl;
delete[] video;
delete[] MAFDs;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment