OpenMP n 体问题
▶ 《并行程序设计导论》第六章中讨论了 n 体问题,分别使用了 MPI,Pthreads,OpenMP 来进行实现,这里是 OpenMP 的代码,分为基本算法和简化算法(引力计算量为基本算法的一半,但是消息传递较为复杂)
● 基本算法
- // omp_nbody_basic.c,OpenMP 基本算法
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <omp.h>
- #define OUTPUT
- #define DEBUG
- #define DIM 2
- #define X 0
- #define Y 1
- typedef double vect_t[DIM];
- const double G = 6.673e-11;
- struct particle_s // 使用一个结构来同时保存一个颗粒的质量,位置,速度
- {
- double m;
- vect_t s;
- vect_t v;
- };
- void Usage(char* prog_name)
- {
- fprintf(stderr, "usage: %s <nThreads> <nParticles> <nTimestep> <sizeTimestep> <outputFrequency> <g|i>\n", prog_name);
- fprintf(stderr, " 'g': inite condition by random\n 'i': inite condition from stdin\n");
- exit();
- }
- void Get_args(int argc, char* argv[], int* thread_count_p, int* n_p, int* n_steps_p, double* delta_t_p, int* output_freq_p, char* g_i_p)
- {
- if (argc != )
- Usage(argv[]);
- *thread_count_p = strtol(argv[], NULL, );
- *n_p = strtol(argv[], NULL, );
- *n_steps_p = strtol(argv[], NULL, );
- *delta_t_p = strtod(argv[], NULL);
- *output_freq_p = strtol(argv[], NULL, );
- *g_i_p = argv[][];
- if (*thread_count_p < || *n_p <= || *n_p % *thread_count_p || *n_steps_p < || *delta_t_p <= || *g_i_p != 'g' && *g_i_p != 'i')
- {
- Usage(argv[]);
- exit();
- }
- # ifdef DEBUG
- printf("Get_args, nThread%2d n %d n_steps %d delta_t %e output_freq %d g_i %c\n",
- *thread_count_p, *n_p, *n_steps_p, *delta_t_p, *output_freq_p, *g_i_p);
- fflush(stdout);
- # endif
- }
- void Gen_init_cond(struct particle_s curr[], int n)
- {
- const double mass = 5.0e24, gap = 1.0e5, speed = 3.0e4;
- //srand(2);
- for (int i = ; i < n; i++)
- {
- curr[i].m = mass;
- curr[i].s[X] = i * gap;
- curr[i].s[Y] = 0.0;
- curr[i].v[X] = 0.0;
- // vel[i][Y] = speed * (2 * rand() / (double)RAND_MAX) - 1);
- curr[i].v[Y] = (i % ) ? -speed : speed;
- }
- }
- void Get_init_cond(struct particle_s curr[], int n)
- {
- printf("For each particle, enter (in order): mass x-coord y-coord x-velocity y-velocity\n");
- for (int i = ; i < n; i++)
- {
- scanf_s("%lf", &curr[i].m);
- scanf_s("%lf", &curr[i].s[X]);
- scanf_s("%lf", &curr[i].s[Y]);
- scanf_s("%lf", &curr[i].v[X]);
- scanf_s("%lf", &curr[i].v[Y]);
- }
- }
- void Output_state(double time, struct particle_s curr[], int n)
- {
- printf("Output_state, time = %.2f\n", time);
- for (int i = ; i < n; i++)
- printf("%2d %10.3e %10.3e %10.3e %10.3e %10.3e\n", i, curr[i].m, curr[i].s[X], curr[i].s[Y], curr[i].v[X], curr[i].v[Y]);
- printf("\n");
- fflush(stdout);
- }
- void Compute_force(int part, vect_t forces[], struct particle_s curr[], int n)
- {
- int k;
- vect_t f_part_k;
- double len, fact;
- for (forces[part][X] = forces[part][Y] = 0.0, k = ; k < n; k++)
- {
- if (k != part)
- {
- f_part_k[X] = curr[part].s[X] - curr[k].s[X];
- f_part_k[Y] = curr[part].s[Y] - curr[k].s[Y];
- len = sqrt(f_part_k[X] * f_part_k[X] + f_part_k[Y] * f_part_k[Y]);
- fact = -G * curr[part].m * curr[k].m / (len * len * len);
- f_part_k[X] *= fact;
- f_part_k[Y] *= fact;
- forces[part][X] += f_part_k[X];
- forces[part][Y] += f_part_k[Y];
- # ifdef DEBUG
- printf("Compute_force, %d, %2d> %10.3e %10.3e %10.3e %10.3e\n", k, len, fact, f_part_k[X], f_part_k[Y]);
- fflush(stdout);
- # endif
- }
- }
- }
- void Update_part(int part, vect_t forces[], struct particle_s curr[], int n, double delta_t)
- {
- const double fact = delta_t / curr[part].m;
- # ifdef DEBUG
- printf("Update_part before, part%2d %10.3e %10.3e %10.3e %10.3e %10.3e %10.3e\n",
- part, curr[part].s[X], curr[part].s[Y], curr[part].v[X], curr[part].v[Y], forces[part][X], forces[part][Y]);
- fflush(stdout);
- # endif
- curr[part].s[X] += delta_t * curr[part].v[X];
- curr[part].s[Y] += delta_t * curr[part].v[Y];
- curr[part].v[X] += fact * forces[part][X];
- curr[part].v[Y] += fact * forces[part][Y];
- # ifdef DEBUG
- printf("Update_part after, part%2d %10.3e %10.3e %10.3e %10.3e)\n",
- part, curr[part].s[X], curr[part].s[Y], curr[part].v[X], curr[part].v[Y]);
- # endif
- }
- void Compute_energy(struct particle_s curr[], int n, double* kin_en_p, double* pot_en_p)// 计算系统轨道能量,没用到
- {
- int i, j;
- vect_t diff;
- double temp;
- for (i = , temp = 0.0; i < n; temp += curr[i].m * curr[i].v[X] * curr[i].v[X] + curr[i].v[Y] * curr[i].v[Y], i++);
- *kin_en_p = temp * 0.5;
- for (i = , temp = .; i < n - ; i++)
- {
- for (j = i + ; j < n; j++)
- {
- diff[X] = curr[i].s[X] - curr[j].s[X];
- diff[Y] = curr[i].s[Y] - curr[j].s[Y];
- temp += -G * curr[i].m * curr[j].m / sqrt(diff[X] * diff[X] + diff[Y] * diff[Y]);
- }
- }
- *pot_en_p = temp;
- }
- int main(int argc, char* argv[])
- {
- int n, part;
- int n_steps, step;
- double delta_t;
- int output_freq;
- struct particle_s* curr; // 颗粒信息
- vect_t* forces; // 引力信息
- int thread_count; // 线程数,用于函数参数和 omp 子句,不是全局变量
- char g_i;
- double start, finish;
- Get_args(argc, argv, &thread_count, &n, &n_steps, &delta_t, &output_freq, &g_i);
- curr = (particle_s*)malloc(n * sizeof(struct particle_s));
- forces = (vect_t*)malloc(n * sizeof(vect_t));
- if (g_i == 'g')
- Gen_init_cond(curr, n);
- else
- Get_init_cond(curr, n);
- start = omp_get_wtime();
- # ifdef OUTPUT
- Output_state(, curr, n);
- # endif
- # pragma omp parallel num_threads(thread_count) default(none) shared(curr, forces, thread_count, delta_t, n, n_steps, output_freq) private(step, part)
- for (step = ; step <= n_steps; step++)
- {
- // memset(forces, 0, n*sizeof(vect_t));
- # pragma omp for
- for (part = ; part < n; part++)
- Compute_force(part, forces, curr, n);
- # pragma omp for
- for (part = ; part < n; part++)
- Update_part(part, forces, curr, n, delta_t);
- # ifdef OUTPUT
- # pragma omp single
- if (step % output_freq == )
- Output_state(step * delta_t, curr, n);
- # endif
- }
- finish = omp_get_wtime();
- printf("Elapsed time = %e ms\n", (finish - start) * );
- free(curr);
- free(forces);
- return ;
- }
● 输出结果。8 进程 16 体,3 秒,时间步长 1 秒,舍去 debug 输出 1.094827e+01 ms;8 进程 1024 体,3600 秒,时间步长 1 秒,舍去 output 和 debug 输出 1.485764e+04 ms
- D:\Code\OpenMP\OpenMPProjectTemp\x64\Debug>OpenMPProjectTemp.exe g
- Output_state, time = 1.00
- 5.000e+24 0.000e+00 3.000e+04 5.273e+04 3.000e+04
- 5.000e+24 1.000e+05 -3.000e+04 1.922e+04 -3.000e+04
- 5.000e+24 2.000e+05 3.000e+04 1.071e+04 3.000e+04
- 5.000e+24 3.000e+05 -3.000e+04 6.802e+03 -3.000e+04
- 5.000e+24 4.000e+05 3.000e+04 4.485e+03 3.000e+04
- 5.000e+24 5.000e+05 -3.000e+04 2.875e+03 -3.000e+04
- 5.000e+24 6.000e+05 3.000e+04 1.614e+03 3.000e+04
- 5.000e+24 7.000e+05 -3.000e+04 5.213e+02 -3.000e+04
- 5.000e+24 8.000e+05 3.000e+04 -5.213e+02 3.000e+04
- 5.000e+24 9.000e+05 -3.000e+04 -1.614e+03 -3.000e+04
- 5.000e+24 1.000e+06 3.000e+04 -2.875e+03 3.000e+04
- 5.000e+24 1.100e+06 -3.000e+04 -4.485e+03 -3.000e+04
- 5.000e+24 1.200e+06 3.000e+04 -6.802e+03 3.000e+04
- 5.000e+24 1.300e+06 -3.000e+04 -1.071e+04 -3.000e+04
- 5.000e+24 1.400e+06 3.000e+04 -1.922e+04 3.000e+04
- 5.000e+24 1.500e+06 -3.000e+04 -5.273e+04 -3.000e+04
- Output_state, time = 2.00
- 5.000e+24 5.273e+04 6.000e+04 9.288e+04 1.641e+04
- 5.000e+24 1.192e+05 -6.000e+04 3.818e+04 -3.791e+03
- 5.000e+24 2.107e+05 6.000e+04 2.116e+04 3.791e+03
- 5.000e+24 3.068e+05 -6.000e+04 1.356e+04 -3.101e+03
- 5.000e+24 4.045e+05 6.000e+04 8.930e+03 3.101e+03
- 5.000e+24 5.029e+05 -6.000e+04 5.739e+03 -2.959e+03
- 5.000e+24 6.016e+05 6.000e+04 3.218e+03 2.959e+03
- 5.000e+24 7.005e+05 -6.000e+04 1.043e+03 -2.929e+03
- 5.000e+24 7.995e+05 6.000e+04 -1.043e+03 2.929e+03
- 5.000e+24 8.984e+05 -6.000e+04 -3.218e+03 -2.959e+03
- 5.000e+24 9.971e+05 6.000e+04 -5.739e+03 2.959e+03
- 5.000e+24 1.096e+06 -6.000e+04 -8.930e+03 -3.101e+03
- 5.000e+24 1.193e+06 6.000e+04 -1.356e+04 3.101e+03
- 5.000e+24 1.289e+06 -6.000e+04 -2.116e+04 -3.791e+03
- 5.000e+24 1.381e+06 6.000e+04 -3.818e+04 3.791e+03
- 5.000e+24 1.447e+06 -6.000e+04 -9.288e+04 -1.641e+04
- Output_state, time = 3.00
- 5.000e+24 1.456e+05 7.641e+04 1.273e+05 -1.575e+03
- 5.000e+24 1.574e+05 -6.379e+04 5.867e+04 2.528e+04
- 5.000e+24 2.319e+05 6.379e+04 2.685e+04 -2.069e+04
- 5.000e+24 3.204e+05 -6.310e+04 1.884e+04 2.228e+04
- 5.000e+24 4.134e+05 6.310e+04 1.235e+04 -2.151e+04
- 5.000e+24 5.086e+05 -6.296e+04 8.111e+03 2.179e+04
- 5.000e+24 6.048e+05 6.296e+04 4.537e+03 -2.163e+04
- 5.000e+24 7.016e+05 -6.293e+04 1.493e+03 2.169e+04
- 5.000e+24 7.984e+05 6.293e+04 -1.493e+03 -2.169e+04
- 5.000e+24 8.952e+05 -6.296e+04 -4.537e+03 2.163e+04
- 5.000e+24 9.914e+05 6.296e+04 -8.111e+03 -2.179e+04
- 5.000e+24 1.087e+06 -6.310e+04 -1.235e+04 2.151e+04
- 5.000e+24 1.180e+06 6.310e+04 -1.884e+04 -2.228e+04
- 5.000e+24 1.268e+06 -6.379e+04 -2.685e+04 2.069e+04
- 5.000e+24 1.343e+06 6.379e+04 -5.867e+04 -2.528e+04
- 5.000e+24 1.354e+06 -7.641e+04 -1.273e+05 1.575e+03
- Elapsed time = 1.094827e-02 seconds
● 简化算法
- // omp_nbody_red.c,OpenMP 简化算法
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <omp.h>
- #define OUTPUT
- //#define DEBUG
- #define DIM 2
- #define X 0
- #define Y 1
- typedef double vect_t[DIM];
- const double G = 6.673e-11;
- struct particle_s
- {
- double m;
- vect_t s;
- vect_t v;
- };
- void Usage(char* prog_name)
- {
- fprintf(stderr, "usage: %s <nThreads> <nParticles> <nTimestep> <sizeTimestep> <outputFrequency> <g|i>\n", prog_name);
- fprintf(stderr, " 'g': inite condition by random\n 'i': inite condition from stdin\n");
- exit();
- }
- void Get_args(int argc, char* argv[], int* thread_count_p, int* n_p, int* n_steps_p, double* delta_t_p, int* output_freq_p, char* g_i_p)
- {
- if (argc != )
- Usage(argv[]);
- *thread_count_p = strtol(argv[], NULL, );
- *n_p = strtol(argv[], NULL, );
- *n_steps_p = strtol(argv[], NULL, );
- *delta_t_p = strtod(argv[], NULL);
- *output_freq_p = strtol(argv[], NULL, );
- *g_i_p = argv[][];
- if (*thread_count_p < || *n_p <= || *n_p % *thread_count_p || *n_steps_p < || *delta_t_p <= || *g_i_p != 'g' && *g_i_p != 'i')
- {
- Usage(argv[]);
- exit();
- }
- # ifdef DEBUG
- printf("Get_args, nThread%2d n %d n_steps %d delta_t %e output_freq %d g_i %c\n",
- *thread_count_p, *n_p, *n_steps_p, *delta_t_p, *output_freq_p, *g_i_p);
- fflush(stdout);
- # endif
- }
- void Gen_init_cond(struct particle_s curr[], int n)
- {
- const double mass = 5.0e24, gap = 1.0e5, speed = 3.0e4;
- //srand(2);
- for (int i = ; i < n; i++)
- {
- curr[i].m = mass;
- curr[i].s[X] = i * gap;
- curr[i].s[Y] = 0.0;
- curr[i].v[X] = 0.0;
- // vel[i][Y] = speed * (2 * rand() / (double)RAND_MAX) - 1);
- curr[i].v[Y] = (i % ) ? -speed : speed;
- }
- }
- void Get_init_cond(struct particle_s curr[], int n)
- {
- printf("For each particle, enter (in order): mass x-coord y-coord x-velocity y-velocity\n");
- for (int i = ; i < n; i++)
- {
- scanf_s("%lf", &curr[i].m);
- scanf_s("%lf", &curr[i].s[X]);
- scanf_s("%lf", &curr[i].s[Y]);
- scanf_s("%lf", &curr[i].v[X]);
- scanf_s("%lf", &curr[i].v[Y]);
- }
- }
- void Output_state(double time, struct particle_s curr[], int n)
- {
- printf("Output_state, time = %.2f\n", time);
- for (int i = ; i < n; i++)
- printf("%2d %10.3e %10.3e %10.3e %10.3e %10.3e\n", i, curr[i].m, curr[i].s[X], curr[i].s[Y], curr[i].v[X], curr[i].v[Y]);
- printf("\n");
- fflush(stdout);
- }
- void Compute_force(int part, vect_t forces[], struct particle_s curr[], int n)
- {
- vect_t f_part_k;
- double len, fact;
- for (int k = part + ; k < n; k++)
- {
- f_part_k[X] = curr[part].s[X] - curr[k].s[X];
- f_part_k[Y] = curr[part].s[Y] - curr[k].s[Y];
- len = sqrt(f_part_k[X] * f_part_k[X] + f_part_k[Y] * f_part_k[Y]);
- fact = -G * curr[part].m * curr[k].m / (len * len * len);
- f_part_k[X] *= fact;
- f_part_k[Y] *= fact;
- forces[part][X] += f_part_k[X]; // 靠前的颗粒加上本次计算结果的相反数
- forces[part][Y] += f_part_k[Y];
- forces[k][X] -= f_part_k[X]; // 靠后的颗粒加上本次计算结果
- forces[k][Y] -= f_part_k[Y];
- # ifdef DEBUG
- printf("Compute_force, k%2d> %10.3e %10.3e %10.3e %10.3e\n", k, len, fact, f_part_k[X], f_part_k[Y]);
- # endif
- }
- }
- void Update_part(int part, vect_t forces[], struct particle_s curr[], int n, double delta_t)
- {
- const double fact = delta_t / curr[part].m;
- # ifdef DEBUG
- printf("Update_part before, part%2d %10.3e %10.3e %10.3e %10.3e %10.3e %10.3e\n",
- part, curr[part].s[X], curr[part].s[Y], curr[part].v[X], curr[part].v[Y], forces[part][X], forces[part][Y]);
- fflush(stdout);
- # endif
- curr[part].s[X] += delta_t * curr[part].v[X];
- curr[part].s[Y] += delta_t * curr[part].v[Y];
- curr[part].v[X] += fact * forces[part][X];
- curr[part].v[Y] += fact * forces[part][Y];
- # ifdef DEBUG
- printf("Update_part after, part%2d %10.3e %10.3e %10.3e %10.3e)\n",
- part, curr[part].s[X], curr[part].s[Y], curr[part].v[X], curr[part].v[Y]);
- # endif
- }
- int main(int argc, char* argv[])
- {
- int n, part;
- int n_steps, step;
- double delta_t;
- int output_freq;
- struct particle_s* curr; // 颗粒信息
- vect_t* forces; // 引力信息
- int nThread, thread, my_rank; // 线程数,用于函数参数和 omp 子句,不是全局变量,当前线程编号(循环变量)
- char g_i;
- double start, finish;
- vect_t* loc_forces; // 每个线程局部引力
- Get_args(argc, argv, &nThread, &n, &n_steps, &delta_t, &output_freq, &g_i);
- curr = (particle_s*)malloc(n * sizeof(struct particle_s));
- forces = (vect_t*)malloc(n * sizeof(vect_t));
- loc_forces = (vect_t*)malloc(nThread*n * sizeof(vect_t));
- if (g_i == 'g')
- Gen_init_cond(curr, n);
- else
- Get_init_cond(curr, n);
- start = omp_get_wtime();
- # ifdef OUTPUT
- Output_state(, curr, n);
- # endif
- # pragma omp parallel num_threads(nThread) default(none) shared(curr, forces, nThread, delta_t, n, n_steps, output_freq, loc_forces) private(step, part,thread, my_rank)
- {
- my_rank = omp_get_thread_num();
- for (step = ; step <= n_steps; step++)
- {
- // memset(loc_forces + my_rank*n, 0, n*sizeof(vect_t));
- # pragma omp for
- for (part = ; part < nThread * n; part++)
- loc_forces[part][X] = loc_forces[part][Y] = 0.0;
- # pragma omp for schedule(static, ) // 注意使用循环调度
- for (part = ; part < n - ; part++)
- Compute_force(part, loc_forces + my_rank * n, curr, n);
- # pragma omp for
- for (part = ; part < n; part++) // 计算引力
- {
- forces[part][X] = forces[part][Y] = 0.0;
- for (thread = ; thread < nThread; thread++)
- {
- forces[part][X] += loc_forces[thread * n + part][X];
- forces[part][Y] += loc_forces[thread * n + part][Y];
- }
- }
- # pragma omp for
- for (part = ; part < n; part++) // 更新位置
- Update_part(part, forces, curr, n, delta_t);
- # ifdef OUTPUT
- if (step % output_freq == )
- {
- # pragma omp single
- Output_state(step*delta_t, curr, n);
- }
- # endif
- }
- }
- finish = omp_get_wtime();
- printf("Elapsed time = %e ms\n", (finish - start) * );
- free(curr);
- free(forces);
- free(loc_forces);
- return ;
- }
● 输出结果,与基本算法类似。8 进程 16 体,3 秒,时间步长 1 秒,舍去 debug 输出 9.887694e-00 ms;8 进程 1024 体,3600 秒,时间步长 1 秒,舍去 output 和 debug 输出 7.857710e+03 ms。数据规模扩大后计算时间趋近基本算法的一半,说明计算花费时间较多,而数据传输花费时间较少。
OpenMP n 体问题的更多相关文章
- Pthreads n 体问题
▶ <并行程序设计导论>第六章中讨论了 n 体问题,分别使用了 MPI,Pthreads,OpenMP 来进行实现,这里是 Pthreads 的代码,分为基本算法和简化算法(引力计算量为基 ...
- MPI n 体问题
▶ <并行程序设计导论>第六章中讨论了 n 体问题,分别使用了 MPI,Pthreads,OpenMP 来进行实现,这里是 MPI 的代码,分为基本算法和简化算法(引力计算量为基本算法的一 ...
- 应用OpenMP的一个简单的设计模式
小喵的唠叨话:最近很久没写博客了,一是因为之前写的LSoftmax后馈一直没有成功,所以在等作者的源码.二是最近没什么想写的东西.前两天,在预处理图片的时候,发现处理200w张图片,跑了一晚上也才处理 ...
- openmp 的使用
http://blog.csdn.net/gengshenghong/article/details/7003110 说明:这部分内容比较基础,主要是分析几个容易混淆的OpenMP函数,加以理解. ( ...
- OpenMP编程总结表
本文对OpenMP 2.0的全部语法——Macro(宏定义).Environment Variables(环境变量).Data Types(数据类型).Compiler Directives(编译指导 ...
- OpenMP共享内存并行编程详解
实验平台:win7, VS2010 1. 介绍 平行计算机可以简单分为共享内存和分布式内存,共享内存就是多个核心共享一个内存,目前的PC就是这类(不管是只有一个多核CPU还是可以插多个CPU,它们都有 ...
- OpenMP并行构造的schedule子句详解 (转载)
原文:http://blog.csdn.net/gengshenghong/article/details/7000979 schedule的语法为: schedule(kind, [chunk_si ...
- 利用OpenMP实现埃拉托斯特尼(Eratosthenes)素数筛法并行化 分类: 算法与数据结构 2015-05-09 12:24 157人阅读 评论(0) 收藏
1.算法简介 1.1筛法起源 筛法是一种简单检定素数的算法.据说是古希腊的埃拉托斯特尼(Eratosthenes,约公元前274-194年)发明的,又称埃拉托斯特尼筛法(sieve of Eratos ...
- 大数据并行计算利器之MPI/OpenMP
大数据集群计算利器之MPI/OpenMP ---以连通域标记算法并行化为例 1 背景 图像连通域标记算法是从一幅栅格图像(通常为二值图像)中,将互相邻接(4邻接或8邻接)的具有非背景值的像素集合提取出 ...
随机推荐
- uva10480最小割集
求最小割集 dinic处理后用dfs对所有点进行标记,遍历整个联接边,起点访问了,终点没访问或者起点没访问,终点访问了就是最小割集之一 #include<map> #include< ...
- torchnet+VGG16计算patch之间相似度
torchnet+VGG16计算patch之间相似度 torch VGG16 similarity 本来打算使用VGG实现siamese CNN的,但是没想明白怎么使用torchnet对模型进行微调. ...
- ssh隧道(通过跳板机)连接mysql
案例: A服务器 B服务器 C服务器mysql 现在mysql服务器C只能通过内网访问,B服务器就能通过内网连接访问到mysql A服务器无法直接连接C服务器mysql,所以要通过跳板机(跳板 ...
- MissingNumber缺失的数字,FirstMissingPositive第一个缺失的正数
MissingNumber问题描述:给定一个数组,数组数字范围是0-n,找到缺失的数字.例如nums={0,1,3},return2. 算法分析:第一种方法,对数组进行排序,然后找到和下标不一致的数字 ...
- Ctrl+K,Ctrl+D
先按下Ctrl+K,然后按下Ctrl+D可以自动调整代码.
- JS代码执行机制
JS代码从编译到执行 我们写出一段JS代码,JS的引擎并不是按照我们书写的顺序从上到下顺序编译并且执行的,首先是按照自己的规则对我们的代码先进行编译,然后从上到下执行编译的代码. 在全局作用域中,JS ...
- 网络编程I/O函数介绍
read和write #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); ssize_t write(in ...
- Wordpress 加载 js 文件到底部
wp_enqueue_script wp_enqueue_script( string $handle, string $src = '', array $deps = array(), string ...
- java编程之常见的排序算法
java常见的排序算法 第一种:插入排序 直接插入排序 1, 直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排 好顺序的,现在要把第n个数插到前面的 ...
- test20181024 ming
题意 分析 考场做法 考虑二分答案,R开到1e9就能过了. 判断答案合法,就判断时间和是否超过拥有的时间就行了.但要把di从小到大排序,不然容易验证贪心是错的. 时间复杂度\(O(n \log n)\ ...