68{
69
71 if(window == NULL)
72 return 1;
73
74
76 if(context == NULL)
77 return 1;
78
79
81 {
82 printf(
"[error] init failed.\n");
83 return 1;
84 }
85
86
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
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
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
106 GLint size= 0;
107 glGetIntegerv(GL_MAX_COMPUTE_SHARED_MEMORY_SIZE, &size);
108 printf(
"shared memory %dKb\n", size / 1024);
110
111#ifndef ATOMIC
112 FILE *out= fopen("min_data.txt", "wt");
113#else
114 FILE *out= fopen("min_atomic.txt", "wt");
115
116
117#endif
118
119
120 for(int logN= 1; logN < logNmax; logN++)
121 {
122 int N= (1<<logN);
123
124
125 glUseProgram(program);
126
127
128 std::chrono::high_resolution_clock::time_point start= std::chrono::high_resolution_clock::now();
129
130 #ifndef ATOMIC
131
132
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
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
144 glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
145
146
147 glDispatchCompute((n+1023) / 1024, 1, 1);
148 }
149
150 #else
151
152 program_uniform(program, "N", (unsigned int) N);
153
154 for(int i=0 ; i < 100; i++)
155 {
156 glDispatchCompute((N+1023) / 1024, 1, 1);
157
158 }
159 #endif
160
161
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
173 printf(
" %03dus\n", (
int) (gpu_time / 1000));
174
175 {
176
177 std::chrono::high_resolution_clock::time_point start= std::chrono::high_resolution_clock::now();
178
179
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
188 printf(
" %02dms %03dus\n", (
int) (cpu_time / 1000000), (
int) ((cpu_time / 1000) % 1000));
189
190
191 fprintf(out, "%d %f %f\n", N, gpu_time / 1000.f, cpu_time / 1000.f);
192
194 }
195 }
196 fclose(out);
197
198
199 quit();
202 return 0;
203}
Context create_context(Window window)
cree et configure un contexte opengl
void release_window(Window window)
destruction de la fenetre.
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().
Window create_window(const int w, const int h, const int major, const int minor)
creation d'une fenetre pour l'application.
void release_context(Context context)
detruit le contexte openGL.
int init(std::vector< const char * > &options)