Вопрос:

C ++ копирует части 2D-массива в другой 2D-массив, производительность

c++ performance multidimensional-array

497 просмотра

1 ответ

18 Репутация автора

В моей программе есть функция, которая вызывается тысячи раз. Функция имеет один аргумент, массив значений bool с длиной = 30000. Основываясь на этом массиве bools, я копирую некоторые строки из глобальной переменной 2d-массива для создания локального 2d-массива. Затем я нахожу среднее значение каждого столбца в локальном 2d массиве. Затем я беру каждое значение в локальном 2-мерном массиве и вычитаю его среднее значение по столбцу, чтобы построить второй локальный 2D-массив.

Программа выполняется так, как задумано, но это заняло слишком много времени, так как я добавил эту функцию. Есть ли более быстрый способ взять подмножество данных из 2d массива и создать новый 2d массив? Есть ли более быстрый способ вычитать среднее значение столбца из каждого значения в 2d массиве? Возможно, я должен смотреть на векторы или объявлять вещи вне функции ...

Спасибо.

double FitValue(bool *X){
    int i,j,k; //loop index
    int counter;
    int numUsedVariables = 0; //
    double sum;
    //find number of selected variables
    for(i=0; i<NUMVARIABLES; i++){ //NUMVARIABLES is a globally defined variable
        if(X[i] == true){
            numUsedVariables += 1;
        }
    }   
    //declare matrix for variable subset    
    alglib::real_2d_array input;
    input.setlength(NUMINDIVS,numUsedVariables); 
    //populate matrix for variable subset
    counter = -1;
    for(i=0; i<NUMVARIABLES; i++){ //NUMVARIABLES is a globally defined variable
        if(X[i] == true){       
            counter++;
            for(j=0; j<NUMINDIVS; j++){ //NUMINDIVS is a globally defined variable      
                input[j][counter] = genotype[i][j]; //genotype is global variable
            }   
        }
    }
    //find the mean of each column
    alglib::real_1d_array colMeans;
    colMeans.setlength(numUsedVariables);
    for(i=0; i<numUsedVariables; i++){
        sum = 0;
        for(j=0; j<NUMINDIVS; j++){
            sum += input[j][i];     
        }   
        colMeans[i] = sum/NUMINDIVS;
    }   
    //declare centered selected markers matrix
    alglib::real_2d_array centeredInput;
    centeredInput.setlength(NUMINDIVS,numUsedVariables);    
    for(i=0; i<numUsedVariables; i++){   
        for(j=0; j<NUMINDIVS; j++){
            centeredInput[j][i] = input[j][i]   - colMeans[i];
        }
    }
    //perform further analysis ...
    //...

}   
Автор: Joe O'Neill Источник Размещён: 08.11.2017 10:26

Ответы (1)


1 плюс

304 Репутация автора

Ваш код замедляется, потому что 2D-массивы доступны в порядке столбцов. Каждый раз, когда процессор получает число из основной памяти, в кеш извлекается целая куча чисел. Помните, C / C ++ хранит массив в первую очередь, если следующий номер, который вам нужен, находится в следующей строке, все кэшированные данные бесполезны. Процессор должен вернуться в основную память, чтобы получить следующий номер. Переход к основной памяти является очень медленным процессом по сравнению с доступом к данным, уже находящимся в кэше.
Чтобы ваш код работал быстрее, вам нужно подумать о том, как реорганизовать ваши данные так, чтобы они были доступны наиболее удобным для кеш способом. Этот код
for(i=0; i<numUsedVariables; i++) for(j=0; j<NUMINDIVS; j++) centeredInput[j][i] = input[j][i] - colMeans[i]; будет работать намного медленнее, чем
for(j=0; j<NUMINDIVS; j++) for(i=0; i<numUsedVariables; i++) centeredInput[j][i] = input[j][i] - colMeans[i];

Автор: kjpus Размещён: 09.11.2017 05:30
Вопросы из категории :
32x32