2017-12-11 5 views
0

일부 자습서와 여기에 stackoverflow에 어떤 사람들의 도움으로, 나는이 기본 병렬 (여러 파일) ​​csv -> 배열 리더를 꿰매 관리했습니다. 더 빨리 할 수 ​​있을까요? 나는 파일을 메모리에 미리로드하거나, 어떻게 든 스레드를 최적화하거나, cuda (일부 작은 경험이있는)에서 일부 작업을 수행 할 가능성에 대해 여기 저기 읽었습니다. 그러나 다음 단계가 무엇인지 단서가 없습니다. 이것을 빨리 할 수있는 제안이 있습니까? :병렬로 배열에 여러 개의 대형 csv 파일을 읽을

// parallel-matrix-multiply.cpp 
// compile with: /EHsc 
#include <windows.h> 
#include <ppl.h> 
#include <iostream> 
#include <random> 

using namespace concurrency;  
using namespace std; 

#include <fstream> 
#include <sstream> 

int main() 
{ 
    int numRows = 360; 
    int numCols = 4096; 

    int** data = new int*[numRows * 120]; 
    for (int i = 0; i < numRows * 120; i++) { 
     data[i] = new int[numCols]; 
    } 

    clock_t starttimetotal = clock(); 
    char comma; // Just a place holder to store the commas 
    char newLine; // Just a place holder to store the newlines 

    int m = 120; //120 files of same format 

    Concurrency::parallel_for(0, m, 
     [&numCols, &numRows, &comma, &newLine, &data](int i) { 

     std::ifstream in("C:/codeoutput/output_" + std::to_string(i + 1) + ".txt"); 

     for (int row = 0; row < numRows; row++) { 
      for (int col = 0; col < numCols; col++) 
      { 
       // Grab Data for the cell in (row,col) 
       in >> data[i * 360 + row][col]; 
       // If this is not the last column grab the comma between the values 
       if (col < numCols - 1) { 
        in >> comma; 
       } 
      } 
      in >> newLine; // Grab the remaining newLine character 
     } 
     in.close(); 
    }); 

    clock_t stoptotal = clock(); 
    double elapsed = (double)(stoptotal - starttimetotal) * 1000.0/CLOCKS_PER_SEC; 
    printf("Time elapsed in ms: %f\n", elapsed); 

    return 0; 
} 
+4

[코드 검토] (https://codereview.stackexchange.com/)에 더 적합 할 수 있습니다. 당신이 할 수있는 간단한 일은 텍스트 파일에서 바이너리 파일로 전환하는 것입니다. 그런 다음 텍스트 파싱에서 시간을 절약하고 루프 내부에서'if' 문을 제거하면 성능에 긍정적 인 영향을 미칩니다. – hnefatl

+2

'int **'(2D, area A)를 사용하여'int *'(1D, 길이 A)를 사용하고 행/열 -> 인덱스 계산을 수동으로 수행 할 수 있습니다. 이렇게하면 주 메모리 조회 횟수가 줄어들어 CPU 저장소에 캐시가 더 많이 남을 수 있습니다. – hnefatl

+2

몇 가지 : 데이터 랭크가 '쉼표'와 'newLine'입니다. 할당 루프를 병렬 파트 내부로 이동할 수도 있습니다. 저수준 플랫폼 종속 I/O 함수를 사용하여 전체 파일을 메모리로 이동 한 다음 메모리를 통해 필요한 데이터를 추출 할 수도 있습니다. –

답변

0

내부 루프는 외부 루프로 이동할 수있는 사항을 계산합니다. 이를 염두에두고 병목 현상이 파일을 읽는 것이 가장 쉽기 때문에 이것이 큰 차이를 만들지는 확실하지 않습니다.

for (int row = 0; row < numRows; row++) { 
     int rowIdx = i * 360 + row; 
     for (int col = 0; col < numCols - 1; col++) 
     { 
      // Grab Data for the cell in (row,col) 
      in >> data[rowIdx][col]; 
      in >> comma; 
     } 

     // Get last column + new line 
     in >> data[rowIdx][numCols - 1]; 
     in >> newLine; // Grab the remaining newLine character 
    } 
+0

나는 시도 할 것이다. Col는 두 번째 루프 이후에 정의되지 않습니다. 120 개 파일 (108 개가 아닌 360 개)은 모두 ~ 200MB이며, SSD에서 읽는 중입니다. 모든 것은 내 PC에서 약 75 초 걸리며 디스크에서 병목 현상을 읽는 중입니까? – user3338991

+0

제 잘못입니다. 문제를 해결해야하는 변화를 만들었습니다. ssd를 사용해도 디스크를 읽으면 병목 현상이 발생할 수 있습니다. 당신은 전체 파일을 메모리에 먼저 읽어 봄으로써 이것을 완화시킬 수 있습니다 (코드를 변경하여). –