2014-09-05 4 views
0

TCLAP - это шаблонная библиотека на основе C++, предназначенная для анализа аргументов командной строки.TCLAP делает многопоточную программу медленнее

Я использую TCLAP для обработки аргументов командной строки в многопоточной программе: аргументы считываются в основной функции, затем инициируются несколько потоков для работы над заданием, определяемым аргументами (некоторые параметры для Задача НЛП).

Я начал показывать количество слов в секунду, обработанное потоками, и я обнаружил, что если я жестко запрограммирую аргументы в главном, а не читая их из cli с использованием TCLAP, пропускная способность равна 6 раз быстрее!

Я использую gcc с аргументом -O2, с которым я вижу увеличение скорости примерно в 10 раз, не оптимизируя во время компиляции (когда TCLAP не используется) ... поэтому кажется, что использование TCLAP каким-то образом отрицает часть преимущества оптимизации компилятора.

Вот что основная функция, единственное место, где я использую TCLAP, выглядит следующим образом:

int main(int argc, char** argv)             
{                    
uint32_t mincount;               
uint32_t dim;                
uint32_t contexthalfwidth;             
uint32_t negsamples;               
uint32_t numthreads;               
uint32_t randomseed;               
string corpus_fname;               
string output_basefname;              
string vocab_fname;               

Eigen::initParallel();              

try {                  
TCLAP::CmdLine cmd("Driver for various word embedding models", ' ', "0.1"); 
TCLAP::ValueArg<uint32_t> dimArg("d","dimension","dimension of word representations",false,300,"uint32_t"); 
TCLAP::ValueArg<uint32_t> mincountArg("m", "mincount", "required minimum occurrence count to be added to vocabulary",false,5,"uint32_t"); 
TCLAP::ValueArg<uint32_t> contexthalfwidthArg("c", "contexthalfwidth", "half window size of a context frame",false,15,"uint32_t"); 
TCLAP::ValueArg<uint32_t> numthreadsArg("t", "numthreads", "number of threads",false,12,"uint32_t"); 
TCLAP::ValueArg<uint32_t> negsamplesArg("n", "negsamples", "number of negative samples for skipgram model",false,15,"uint32_t"); 
TCLAP::ValueArg<uint32_t> randomseedArg("s", "randomseed", "seed for random number generator",false,2014,"uint32_t"); 
TCLAP::UnlabeledValueArg<string> corpus_fnameArg("corpusfname", "file containing the training corpus, one paragraph or sentence per line", true, "corpus", "corpusfname"); 
TCLAP::UnlabeledValueArg<string> output_basefnameArg("outputbasefname", "base filename for the learnt word embeddings", true, "wordreps-", "outputbasefname"); 
TCLAP::ValueArg<string> vocab_fnameArg("v", "vocabfname", "filename for the vocabulary and word counts", false, "wordsandcounts.txt", "filename"); 
cmd.add(dimArg);                
cmd.add(mincountArg);              
cmd.add(contexthalfwidthArg);            
cmd.add(numthreadsArg);              
cmd.add(randomseedArg);              
cmd.add(corpus_fnameArg);             
cmd.add(output_basefnameArg);            
cmd.add(vocab_fnameArg);              
cmd.parse(argc, argv);              

mincount = mincountArg.getValue();           
dim = dimArg.getValue();              
contexthalfwidth = contexthalfwidthArg.getValue();       
negsamples = negsamplesArg.getValue();          
numthreads = numthreadsArg.getValue();          
randomseed = randomseedArg.getValue();          
corpus_fname = corpus_fnameArg.getValue();         
output_basefname = output_basefnameArg.getValue();       
vocab_fname = vocab_fnameArg.getValue();          
}                   
catch (TCLAP::ArgException &e) {};   

/*                   
uint32_t mincount = 5;              
uint32_t dim = 50;               
uint32_t contexthalfwidth = 15;            
uint32_t negsamples = 15;             
uint32_t numthreads = 10;             
uint32_t randomseed = 2014;             
string corpus_fname = "imdbtrain.txt";          
string output_basefname = "wordreps-";          
string vocab_fname = "wordsandcounts.txt";         
*/                   

string test_fname = "imdbtest.txt";           
string output_fname = "parreps.txt";           
string countmat_fname = "counts.hdf5";          
Vocabulary * vocab;                            

vocab = determineVocabulary(corpus_fname, mincount);       
vocab->dump(vocab_fname);             

Par2VecModel p2vm = Par2VecModel(corpus_fname, vocab, dim, contexthalfwidth, negsamples, randomseed); 
p2vm.learn(numthreads);              
p2vm.save(output_basefname);             
p2vm.learnparreps(test_fname, output_fname, numthreads); 

}  

используется единственное место, многопоточность в Par2VecModel :: узнать функции:

void Par2VecModel::learn(uint32_t numthreads) {         
thread* workers;                
workers = new thread[numthreads];           
uint64_t numwords = 0;              
bool killflag = 0;               
uint32_t randseed;               

ifstream filein(corpus_fname.c_str(), ifstream::ate | ifstream::binary);  
uint64_t filesize = filein.tellg();           

fprintf(stderr, "Total number of in vocab words to train over: %u\n", vocab->gettotalinvocabwords()); 

for(uint32_t idx = 0; idx < numthreads; idx++) {        
    randseed = eng();              
    workers[idx] = thread(skipgram_training_thread, this, numthreads, idx, filesize, randseed, std::ref(numwords)); 
}                   

thread monitor(monitor_training_thread, this, numthreads, std::ref(numwords), std::ref(killflag)); 

for(uint32_t idx = 0; idx < numthreads; idx++)        
    workers[idx].join();              

killflag = true;                
monitor.join();                
} 

Это раздел не включает TCLAP вообще, так что происходит? (Я также использую функции C++ 11, так что есть флаг -std = C++ 11, если это имеет значение)

+0

Не видя никакого кода, это невозможно сказать. – nvoigt

ответ

0

Так что это было открыто в течение длительного времени, и это предложение больше не может быть быть полезным, но сначала я должен проверить, что произойдет, если вы замените TCLAP на «простой» парсер (т.е. просто подайте аргументы в командной строке в определенном фиксированном порядке и преобразуйте их в нужный тип). Это высоко маловероятно, что проблема связана с TCLAP (т. Е. Я не могу представить какой-либо механизм такого поведения). Тем не менее, вполне возможно, что с жестко закодированными значениями компилятор может выполнять некоторые оптимизации времени компиляции, которые невозможны, когда эти значения должны быть переменными. Однако степень разницы в производительности кажется несколько патологической, поэтому я все еще скептически отношусь к тому, что не происходит что-то еще.

Смежные вопросы