Beruflich Dokumente
Kultur Dokumente
OLEH:
NURUL FATHANAH M. (P2700215018)
Tugas 4
Dijkstra Shortest Path Algorithm
Program dikerjakan di Laptop Asus X455LDB dengan spesifikasi sebagai berikut :
Listing Program
complete_graph.h
//==============================================================
//
// SAMPLE SOURCE CODE - SUBJECT TO THE TERMS OF SAMPLE CODE LICENSE AGREEMENT,
// http://software.intel.com/en-us/articles/intel-sample-source-code-license-agreement/
//
// Copyright 2013 Intel Corporation
//
// THIS FILE IS PROVIDED "AS IS" WITH NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
// NOT LIMITED TO ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE, NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS.
//
// ===============================================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __INTEL_COMPILER
#include <cilk/cilk.h>
#endif
#include "timer.h"
#include "complete_graph.h"
// Graph adjacency matrix
unsigned int graph[VNUM][VNUM];
// Shortest path length result matrix of the optimized
unsigned int spath_opt[VNUM][VNUM];
// Shortest path previous vertex matrix of the optimized
unsigned int pvertex_opt[VNUM][VNUM];
#ifdef CHECK_RESULT
// Shortest path length result matrix of base line for correctness checking
unsigned int spath_base[VNUM][VNUM];
// Shortest path previous vertex matrix of base line for correctness checking
unsigned int pvertex_base[VNUM][VNUM];
#endif
// Description:
// Create a complete graph having VNUM vertexes and save it to adjacency matrix "graph"
// Initialize shortest path length to edge length
// Initialize previous vertex on each path to its start vertex
void init_graph(void)
{
int i,j;
srand(RSEED);
for (i = 0;i < VNUM;++i) {
for (j = i; j < VNUM;++j) {
if (i == j)
// Set adjacency matrix and shortest path matrix diagonal to zero
graph[i][j] = 0;
else
// Create edge length between "EDGE_MIN" and "EDGE_MAX" by calling random
number generator function
graph[i][j] = graph[j][i] = (int) (EDGE_MIN + (EDGE_MAX * (rand() / (RAND_MAX
+ EDGE_MIN))));
}
}
}
// Description:
// Dump the graph adjacency matrix to a file named EDGE_FILE_NAME
// For debug purpose
void dump_graph_edge(void)
{
int i,j;
// Edge dumping file pointer
FILE * f_edge;
// Open the dumping file for writing
// If previous vertex on the path is "start" we arrive at the first edge and print it
out
printf("%10u
----> %10u:
%10u\n",start,end,graph[start][end]);
else {
// If previous vertex on the path isn't "start" backtrace the path
backtracing_spath(start,pvertex_opt[start][end]);
// Print out current edge and its length
printf("%10u
----> %10u:
%10u\n",pvertex_opt[start][end],end,graph[pvertex_opt[start][end]][end]);
}
}
// Description
// Print out the length and the edges of a shortest path from "start" to "end"
void print_spath(unsigned int start, unsigned int end)
{
printf("The shortest path length from %u to %u is
\"%u\".\n",start,end,spath_opt[start][end]);
printf("The edges on this path are:\n");
// Call the help function to backtrace the path
backtracing_spath(start,end);
}
#ifdef CHECK_RESULT
// Description
// Calculate the shortest path between each pair of vertexes in the complete graph using
Disjkstra algorithm without any optimization
// Its result will be used for correctness checking
#pragma optimize ("",off)
void calculate_shortest_path_base(void)
{
int i;
// Temporary array storing intermedia path length result to each vertex
unsigned int vtemp[VNUM];
// Flag array:
// "1" means the shortest path hasn't been finished
// "0" menas the shortest path has been finished
unsigned char vflag[VNUM];
// Main loop calculate the shortest path to all other vertexes from vertex "i" in each
iteration
for (i = 0;i < VNUM;++i) {
int j;
// Initialize intermedia path length to INFINITE
memset(vtemp,0xff,VNUM*sizeof(unsigned int));
// Place the source vertex
vtemp[i] = 0;
pvertex_base[i][i] = i;
// Intialize flag array to all "1"
memset(vflag,1,VNUM);
// Calculate the "j+1"th shortest path from vertext "i"
for (j = 0;j < VNUM;++j) {
// minval: shortest path lengh in vtemp
// minpos: index of the vertex having the shortest path length
unsigned int minval, minpos;
int k;
// Main loop calculate the shortest path to all other vertexes from vertex "i" in each
iteration
for (i = 0;i < VNUM;++i) {
int j;
// Initialize intermedia path length to INFINITE
memset(vtemp,0xff,VNUM*sizeof(unsigned int));
// Place the source vertex
vtemp[i] = 0;
pvertex_opt[i][i] = i;
// Intialize flag array to all "1"
memset(vflag,1,VNUM);
// Calculate the "j+1"th shortest path from vertext "i"
for (j = 0;j < VNUM;++j) {
// minval: shortest path lengh in vtemp
// minpos: index of the vertex having the shortest path length
unsigned int minval, minpos;
int k;
// Find the index of vertex having the shortest path in vtemp using Array
Notation built-in reduction function "__sec_recduce_min_ind"
// Find the shortest path length using the index
minpos = __sec_reduce_min_ind(vtemp[:]);
minval = vtemp[minpos];
// Store the shortest path length found to result matrix
spath_opt[i][minpos] = minval;
// Update the length value of the vertex found to INFINITE so that it will be
ignored in next round of MIN reduction
vtemp[minpos] = INFINITE;
// Flag the path to the vertex found as finished
vflag[minpos] = 0;
// Update unfinished vertexes path length value using edge length to the found
vertex using Array Notation
if (vflag[:] && ((graph[minpos][:] + minval) < vtemp[:])) {
vtemp[:] = (graph[minpos][:] + minval);
pvertex_opt[i][:] = minpos;
}
}
}
}
// Description
// Calculate the shortest path between each pair of vertexes in the complete graph using
Disjkstra algorithm with Cilk_for
void calculate_shortest_path_cfor(void)
{
// Main loop calculate the shortest path to all other vertexes from vertex "i" in each
iteration
// Declare loop control variable in "cilk_for" statement
cilk_for (int i = 0;i < VNUM;++i) {
// Declare temporary arrays inside "cilk_for" loop body to make them private
// Temporary array storing intermedia path length result to each vertex
unsigned int vtemp[VNUM];
// Flag array:
// "1" means the shortest path hasn't been finished
// "0" menas the shortest path has been finished
sp_main.h
//
//
//
//
//
//
//
//
//
//
//
SAMPLE SOURCE CODE - SUBJECT TO THE TERMS OF SAMPLE CODE LICENSE AGREEMENT,
http://software.intel.com/en-us/articles/intel-sample-source-code-license-agreement/
Copyright 2013 Intel Corporation
THIS FILE IS PROVIDED "AS IS" WITH NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS.
===============================================================
#include
#include
#include
#include
<stdio.h>
<stdlib.h>
<string.h>
<math.h>
#include "timer.h"
#include "complete_graph.h"
// Run set flag
#define RUN_ALL
#define RUN_SERIAL
#define RUN_AN
#define RUN_CFOR
#define RUN_AN_CFOR
0x00000001
0x00000002
0x00000004
0x00000008
0x00000010
// Description
// Main function of the program
// Return value: 0 on success and -1 on an invalid user input path
int main(int argc, char * argv[])
{
// Timer
CUtilTimer tm;
// Create a graph
init_graph();
#ifdef DEBUG
// Dump the graph adjacency matrix to a file for debugging
dump_graph_edge();
#endif
// Initialize run set flag to run all tests.
unsigned int run_flag = 0;
int option = -1;
#ifdef __INTEL_COMPILER
#ifdef PERF_NUM
// Run all tests if PERF_NUM defined
run_flag = RUN_ALL;
#else
if(argc>1) {
// Prints out instructions and quits
if(argv[1][0] == 'h') {
printf("Dijkstra shortest path algorithm for a complete graph having 115
vertexes\n");
printf("[0] all tests\n[1] serial/scalar\n[2] serial/array notation\n[3]
cilk_for/scalar\n[4] cilk_for/array notation\n");
#ifdef _WIN32
system("PAUSE");
#endif // _WIN32
return 0;
}
// option is assumed an option
else
option = atoi(argv[1]);
}
else {
#endif
}
if (run_flag & (RUN_AN_CFOR|RUN_ALL)) {
printf("\nStarting cilk_for + array notation shortest path...\n");
// Start the timer
tm.start();
// Calcuate the shortest path
calculate_shortest_path_an_cfor();
// Stop the timer
tm.stop();
// Print the time consumed by calculating the shortest path
avg_time[3] += tm.get_time();
printf("Calculating finished. Time taken is %.0fms.\n",tm.get_time()*1000.0);
#ifdef CHECK_RESULT
if (!check_result()) {
printf("Result is incorrect!\n");
#ifdef _WIN32
system("PAUSE");
#endif
return -1;
}
#endif
}
printf("\n");
#endif
#ifdef PERF_NUM
}
#ifdef __INTEL_COMPILER
printf("avg time: %.0fms\n", avg_time[:]*1000.0/5);
#else
printf("avg time: %.0fms\n", avg_time[0]*1000.0/5);
#endif
#endif
#ifdef CHECK_RESULT
printf("Result is correct!\n");
#endif
#ifdef _WIN32
system("PAUSE");
#endif
return 0;
}
timer.h
//==============================================================
//
// SAMPLE SOURCE CODE - SUBJECT TO THE TERMS OF SAMPLE CODE LICENSE AGREEMENT,
// http://software.intel.com/en-us/articles/intel-sample-source-code-license-agreement/
//
// Copyright 2013 Intel Corporation
//
// THIS FILE IS PROVIDED "AS IS" WITH NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT
// NOT LIMITED TO ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// Registers the current clock tick value in m_end_clock_tick, current time value in
m_end_time
// Windows uses __rdtsc for clock ticks and
QueryPerformanceFrequency/QueryPerformanceCounter for time
// Linux*/OS X* uses the rdtsc instruction for clock ticks and get_timeofday for time
void CUtilTimer::stop() {
#ifdef _WIN32
// Clock ticks
m_end_clock_tick = __rdtsc();
// Time
unsigned __int64 now;
QueryPerformanceCounter((LARGE_INTEGER *)&now);
m_end_time = static_cast<double>(now) / m_frequency;
#else
// Clock ticks
unsigned lower, higher;
__asm__ __volatile__("rdtsc":"=a"(lower), "=d"(higher));
m_end_clock_tick = ((unsigned long long)lower)|(((unsigned long long)higher)<<32);
// Time
struct timeval start;
gettimeofday(&start, 0);
m_end_time = ((double) start.tv_sec + (double) start.tv_usec/1000000.0);
#endif
}
// Description:
// Returns the number of clock ticks taken between start and stop
long long CUtilTimer::get_ticks() {
return (m_end_clock_tick - m_start_clock_tick);
}
// Description:
// Returns the number of seconds taken between start and stop
double CUtilTimer::get_time() {
return (m_end_time - m_start_time);
}
Running Program
Untuk Vertex 115
Serial
Serial Array
cilk_for
Scalar(ms) Notation(ms) Scalar (ms)
41
16
18
124
77
105
268
229
245
573
506
543
1029
935
900
1718
1584
1587
2713
2518
2510
3917
3538
3759
5596
5008
5751
7597
6847
6433
cilk_for Array
Notation (ms)
7
35
86
190
357
600
949
1360
1912
2636
Waktu (ms)
7000
6000
5000
Serial Scalar(ms)
4000
3000
2000
1000
0
115 215 315 415 515 615 715 815 915 1015
Vertex