Для чего нужен start и finalize в main функции C++

Рейтинг: 0Ответов: 1Опубликовано: 04.04.2023

Изучаю код на языке C++, но не могу разобраться для чего в функции main есть start и finalize. Я не так хорошо знаю C++, но все же необходимо разобрать код, но впервые вижу такие конструкции, подскажите, пожалуйста, что это и для чего?

int main(int argc, char **argv)
{
    MPI_Init(NULL, NULL);

    // Find out rank, size
    int instance_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &instance_rank);
    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    char* tracefile;
    tracefile = getenv("TVTRACE");
    if( tracefile != NULL ){
        printf( "tv tracefile=%s\n", tracefile);
        MPI_Pcontrol(TRACEFILES, NULL, tracefile, 0);
    }
    else{
        MPI_Pcontrol(TRACEFILES, NULL, "trace", 0);
    }

    MPI_Pcontrol(TRACELEVEL, 1,1,1);
    MPI_Pcontrol(TRACENODE, 1000000, 0, 1);     
    
    MPI_Status status;


start:
    printf("Instance rank: %d, world_size: %d. Start\n", instance_rank, world_size);
    
    // Время для замеров
    double start_time, end_time, delta;
    start_time = MPI_Wtime();

    ProcessInitData pid;
    int i, j, k;
    
    //Здесь код симплекс метода
    if(instance_rank == 0){
        SimplexTable st = init_random_simplex_table(2, 3);

        print_matrix("table", st.table, st.m + 1, st.m + st.n);
        print_vector("table z", st.z, st.m + 1);
        print_vector("table b", st.b, st.m + 1);

        int row_length = st.n + st.m;
        //чтобы получилось обработать и нечетно количество условий
        int max_rows_per_proc = (st.m + 1) / world_size;

        double *q;
        q = malloc(sizeof(double) * (row_length));
        for(i = 0; i < row_length; i++){
            q[i] = st.table[0][i];
        }

        MPI_Pcontrol(TRACEEVENT, "entry", 1, 0, "");
        for(i = 0; i < world_size; i++){
            ProcessInitData data;
            data = get_process_init_data(st, max_rows_per_proc, row_length, i);
            //рассылаем данные слейвам
            if(i > 0){
                send_process_init_data(data, i);
            } else {
                pid = data;
            }
        }
        MPI_Pcontrol(TRACEEVENT, "exit", 1, 0, "");

        //тут уже параллельность
        while(1){
            int column = -1;
            //смотрим только по количеству переменных
            for(i = 0; i < st.n; i++){
                if(q[i] < 0){
                    column = i;
                    break;
                }
            }

            MPI_Pcontrol(TRACEEVENT, "entry", 2, 0, "");
            //рассылаем всем column, он же признак завершения работы всего
            MPI_Bcast(&column, 1, MPI_INT, instance_rank, MPI_COMM_WORLD);
            if(column < 0){
                break;
            } 
            MPI_Pcontrol(TRACEEVENT, "exit", 2, 0, "");


            //работаем сами
            ProcessWorkResult work_res;
            work_res = process_work(pid, column);

            //получаем результаты, выбираем лучший
            int min_L = 0;

            MPI_Pcontrol(TRACEEVENT, "entry", 3, 0, "");
            ProcessWorkResult any_process_res, best_work_res = work_res;
            for(i=1; i < world_size; i++){
                any_process_res = recieve_process_work_result(i, &status);               
                if(any_process_res.min_X < best_work_res.min_X){
                    best_work_res = any_process_res;
                    min_L = i;
                }
            }
            MPI_Pcontrol(TRACEEVENT, "exit", 3, 0, "");   
            
            //сообщаем слевам, кто лучший
            MPI_Bcast(&min_L, 1, MPI_INT, instance_rank, MPI_COMM_WORLD);
            double *g;
            double h;
            MPI_Pcontrol(TRACEEVENT, "entry", 4, 0, "");
            if(min_L != 0){
                //лучший процесс - один из слейвов
                //ждем g и h
                g = malloc(sizeof(double) * (pid.col_count));
                MPI_Bcast(g, pid.col_count, MPI_DOUBLE, min_L, MPI_COMM_WORLD);
                MPI_Bcast(&(h), 1, MPI_DOUBLE, min_L, MPI_COMM_WORLD);
            } else {
                //лучший процесс - мастер
                //отпрака всем g=С[row_no] и h=b[row_no]
                g = pid.C[best_work_res.row_no];
                h = pid.b[best_work_res.row_no];
                MPI_Bcast(g, pid.col_count, MPI_DOUBLE, instance_rank, MPI_COMM_WORLD);
                MPI_Bcast(&(h), 1, MPI_DOUBLE, instance_rank, MPI_COMM_WORLD);
            }
            MPI_Pcontrol(TRACEEVENT, "exit", 4, 0, "");


            //а здесь у нас уже есть g и h
            //изменяем C и b
            
            if (min_L == instance_rank){
                //особенности процесса с минимумом
                for(i = 0; i < row_length; i++){
                    pid.C[best_work_res.row_no][i] = g[i]/g[column];
                }
                pid.b[best_work_res.row_no] = h / g[column];
            }

            //особенности мастера
            double a;
            if(g[column] != 0){
                a = q[column] / g[column];
            } else {
                a = 0;
            }

            for(i = 0; i < row_length; i++){
                q[i] = q[i] - (a * g[i]);
            }
            st.z[0] = st.z[0] - a * h;
        }
        
        for(i = 0; i < row_length; i++){
            st.table[0][i] = q[i];
        }

        MPI_Pcontrol(TRACEEVENT, "entry", 5, 0, ""); 
        for(k = 0; k < world_size; k++){
            ProcessInitData data;
            int max_rows_per_proc;
            if(!k){
                data = pid;
                max_rows_per_proc = pid.row_count;
            } else {
                data = recieve_process_init_data(k, &status);
            }
            
            for(i = 0; i < data.row_count; i++){
                int row_index = k * max_rows_per_proc + i + 1;
                for(j = 0; j < data.col_count; j++){
                    st.table[row_index][j] = data.C[i][j];
                }
                st.z[row_index] = data.b[i];
            }

            if(k != 0)
            {
                free_matrix(data.C, data.row_count);
                free_vector(data.b);
            }
        }
        MPI_Pcontrol(TRACEEVENT, "exit", 5, 0, "");


//        print_matrix("table", st.table, st.m + 1, st.m + st.n);
        print_vector("table z", st.z, st.m + 1);
//        print_vector("table b", st.b, st.m + 1);

        //чистим данные!!!
        free_matrix(st.table, st.m + 1);
        free_vector(st.z);
        free_vector(st.b);
    } else {
        //получаем информацию для инициализации
        MPI_Pcontrol(TRACEEVENT, "entry", 6, 0, "");
        pid = recieve_process_init_data(0, &status);
        MPI_Pcontrol(TRACEEVENT, "exit", 6, 0, "");
        
        while(1){
            int column;
            //получаем column или финалайз
            MPI_Bcast(&(column), 1, MPI_INT, 0, MPI_COMM_WORLD);
            printf("Instance %d, column %d\n", instance_rank, column);
            if(column < 0){
                break;
            }

            ProcessWorkResult work_res;
            work_res = process_work(pid, column);
            //шлем результат мастеру
            send_process_work_result(work_res, 0);

            //получаем min_L
            int min_L;
            MPI_Bcast(&(min_L), 1, MPI_INT, 0, MPI_COMM_WORLD);

            double *g;
            double h;
            MPI_Pcontrol(TRACEEVENT, "entry", 7, 0, "");
            if(min_L != instance_rank){
                //лучший процесс не мы
                //ждем g и h
                g = malloc(sizeof(double) * (pid.col_count));
                MPI_Bcast(g, pid.col_count, MPI_DOUBLE, min_L, MPI_COMM_WORLD);
                MPI_Bcast(&(h), 1, MPI_DOUBLE, min_L, MPI_COMM_WORLD);
            } else {
                //лучший процесс - мы
                //отпрака всем g=С[row_no] и h=b[row_no]
                g = pid.C[work_res.row_no];
                h = pid.b[work_res.row_no];
                MPI_Bcast(g, pid.col_count, MPI_DOUBLE, instance_rank, MPI_COMM_WORLD);
                MPI_Bcast(&(h), 1, MPI_DOUBLE, instance_rank, MPI_COMM_WORLD);
            }
            MPI_Pcontrol(TRACEEVENT, "exit", 7, 0, "");
            

            //а здесь у нас уже есть g и h
            //изменяем C и b
            //особенность процесс с минимумом
            if(min_L == instance_rank){
                for(i = 0; i < pid.col_count; i++){
                    pid.C[work_res.row_no][i] = g[i]/g[column];
                }
                pid.b[work_res.row_no] = h / g[column];
            }

            if(min_L != instance_rank){
                free_vector(g);
            }
        }

        //отсылаем C и b
        MPI_Pcontrol(TRACEEVENT, "entry", 8, 0, "");
        send_process_init_data(pid, 0);
        MPI_Pcontrol(TRACEEVENT, "exit", 8, 0, "");
        
        //чистим данные
        free_matrix(pid.C, pid.row_count);
        free_vector(pid.b);
    }

finalize:
    end_time = MPI_Wtime();
    delta = end_time - start_time;
    printf("Instance rank: %d, finished for %lf seconds\n", instance_rank, delta);
    
    //finalizing
    MPI_Finalize();
    
    return EXIT_SUCCESS;
}

Ответы

▲ 0Принят
#include <iostream>

int main() {
    std::cout << "Start" << std::endl;

start:
    std::cout << "123" << std::endl;
    goto finalize;

finalize:
    std::cout << "456" << std::endl;
    return 0;
}

В принципе вам уже ответили, но вот короткая реализация идеи в вашем коде.