gKit2 light
Loading...
Searching...
No Matches
min_data.cpp File Reference
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <algorithm>
#include <chrono>
#include "window.h"
#include "vec.h"
#include "program.h"
#include "uniforms.h"

Go to the source code of this file.

Functions

int init ()
int quit ()
int main (int argc, char **argv)

Variables

GLuint program = 0
GLuint input_buffer = 0
GLuint tmp_buffer = 0
std::vector< int > input
const int logNmax = 26

Function Documentation

◆ init()

int init ( )

Definition at line 28 of file min_data.cpp.

29{
30 srand(time(nullptr));
31
32 int o= rand() % 10000;
33 for(int i= 0; i < (1<<logNmax); i++)
34 input.push_back( o + rand() % 10000);
35
36 glGenBuffers(1, &input_buffer);
37 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, input_buffer);
38 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int) * input.size(), input.data(), GL_STATIC_READ);
39
40 glGenBuffers(1, &tmp_buffer);
41 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, tmp_buffer);
42 glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int) * input.size(), input.data(), GL_STREAM_READ);
43
44#define ATOMIC
45
46#ifndef ATOMIC
47 // version reduction globale
48 program= read_program("gkit2_tutos/min_data.glsl");
49#else
50 // version atomique
51 program= read_program("gkit2_tutos/min_atomic.glsl");
52 program_print_errors(program);
53#endif
54
55 return 0;
56}
GLuint read_program(const char *filename, const char *definitions)
Definition program.cpp:217
int program_print_errors(const GLuint program, const char *filename)
affiche les erreurs de compilation.
Definition program.cpp:461

◆ quit()

int quit ( )

Definition at line 58 of file min_data.cpp.

59{
60 release_program(program);
61 glDeleteBuffers(1, &input_buffer);
62 glDeleteBuffers(1, &tmp_buffer);
63 return 0;
64}
int release_program(const GLuint program)
detruit les shaders et le program.
Definition program.cpp:240

◆ main()

int main ( int argc,
char ** argv )

Definition at line 67 of file min_data.cpp.

68{
69 // etape 1 : creer la fenetre
70 Window window= create_window(1024, 640, 4,3); // openGL version 4.3
71 if(window == NULL)
72 return 1;
73
74 // etape 2 : creer un contexte opengl pour pouvoir dessiner
75 Context context= create_context(window);
76 if(context == NULL)
77 return 1;
78
79 // etape 3 : creation des objets
80 if(init() < 0)
81 {
82 printf("[error] init failed.\n");
83 return 1;
84 }
85
86 // taille max des groupes de shaders
87 GLint threads_max= 0;
88 glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &threads_max);
89 printf("threads max %d\n", threads_max);
90
91 // dimension max des groupes de shaders
92 GLint size_max[3]= { };
93 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &size_max[0]);
94 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &size_max[1]);
95 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &size_max[2]);
96 printf("size max %d %d %d\n", size_max[0], size_max[1], size_max[2]);
97
98 // nombre max de groupes de shaders
99 GLint groups_max[3]= { };
100 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &groups_max[0]);
101 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 1, &groups_max[1]);
102 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 2, &groups_max[2]);
103 printf("groups max %d %d %d\n", groups_max[0], groups_max[1], groups_max[2]);
104
105 // taille de la memoire partagee
106 GLint size= 0;
107 glGetIntegerv(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE, &size);
108 printf("shared memory %dKb\n", size / 1024);
109 printf("\n");
110
111#ifndef ATOMIC
112 FILE *out= fopen("min_data.txt", "wt");
113#else
114 FILE *out= fopen("min_atomic.txt", "wt");
115 //~ FILE *out= fopen("min_atomic_shared.txt", "wt");
116 //~ FILE *out= fopen("min_copy.txt", "wt");
117#endif
118
119 // pour N= 2, 4, 8, ... 2^n
120 for(int logN= 1; logN < logNmax; logN++)
121 {
122 int N= (1<<logN);
123
124 // run
125 glUseProgram(program);
126
127 // mesure le temps d'execution du dispatch
128 std::chrono::high_resolution_clock::time_point start= std::chrono::high_resolution_clock::now();
129
130 #ifndef ATOMIC
131 // version reduction avec synchronisation externe
132 // 1ere etape
133 program_uniform(program, "N", (unsigned int) N);
134 program_uniform(program, "n", (unsigned int) 0);
135 glDispatchCompute((N+1023) / 1024, 1, 1);
136
137 // etapes suivantes
138 program_uniform(program, "N", (unsigned int) 0);
139 for(int n= N/2; n > 1; n= n/2)
140 {
141 program_uniform(program, "n", (unsigned int) n);
142
143 // attendre que les resultats temporaires sont dispos
144 glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
145
146 //~ for(int i=0 ; i < 100; i++)
147 glDispatchCompute((n+1023) / 1024, 1, 1);
148 }
149
150 #else
151 // version avec synchronisation "atomique"
152 program_uniform(program, "N", (unsigned int) N);
153 // un seul dispatch
154 for(int i=0 ; i < 100; i++)
155 {
156 glDispatchCompute((N+1023) / 1024, 1, 1);
157 //~ glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
158 }
159 #endif
160
161 // recupere les resultats tmp
162 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
163
164 std::chrono::high_resolution_clock::time_point stop= std::chrono::high_resolution_clock::now();
165 long int gpu_time= std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start).count();
166
167 std::vector<int> tmp(input.size(), 0);
168 glBindBuffer(GL_SHADER_STORAGE_BUFFER, tmp_buffer);
169 glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, sizeof(int) * tmp.size(), tmp.data());
170
171 printf("gpu min %d:", tmp[1]);
172 //~ printf(" %02dms %03dus\n", (int) (gpu_time / 1000000), (int) ((gpu_time / 1000) % 1000));
173 printf(" %03dus\n", (int) (gpu_time / 1000));
174
175 {
176 // verification
177 std::chrono::high_resolution_clock::time_point start= std::chrono::high_resolution_clock::now();
178
179 // version sequentielle cpu
180 int m= input[0];
181 for(int i= 1; i < N; i++)
182 m= std::min(m, input[i]);
183
184 std::chrono::high_resolution_clock::time_point stop= std::chrono::high_resolution_clock::now();
185 long int cpu_time= std::chrono::duration_cast<std::chrono::nanoseconds>(stop - start).count();
186
187 printf("cpu min %d:", m);
188 printf(" %02dms %03dus\n", (int) (cpu_time / 1000000), (int) ((cpu_time / 1000) % 1000));
189
190 // ecrire les temps d'execution dans le fichier
191 fprintf(out, "%d %f %f\n", N, gpu_time / 1000.f, cpu_time / 1000.f);
192
193 printf("\n");
194 }
195 }
196 fclose(out);
197
198 // etape 5 : nettoyage
199 quit();
200 release_context(context);
201 release_window(window);
202 return 0;
203}
Context create_context(Window window)
cree et configure un contexte opengl
Definition window.cpp:358
void release_window(Window window)
destruction de la fenetre.
Definition window.cpp:328
void printf(Text &text, const int px, const int py, const char *format,...)
affiche un texte a la position x, y. meme utilisation que printf().
Definition text.cpp:140
Window create_window(const int w, const int h, const int major, const int minor)
creation d'une fenetre pour l'application.
Definition window.cpp:262
void release_context(Context context)
detruit le contexte openGL.
Definition window.cpp:439
int init(std::vector< const char * > &options)

Variable Documentation

◆ program

GLuint program = 0

Definition at line 19 of file min_data.cpp.

◆ input_buffer

GLuint input_buffer = 0

Definition at line 20 of file min_data.cpp.

◆ tmp_buffer

GLuint tmp_buffer = 0

Definition at line 21 of file min_data.cpp.

◆ input

std::vector<int> input

Definition at line 23 of file min_data.cpp.

◆ logNmax

const int logNmax = 26

Definition at line 26 of file min_data.cpp.