Я очень неравнодушен к pthreads и реализую асинхронную оболочку ontop считывателя, которая синхронизируется при запросе следующего набора данных.
Это самый простой способ, который я могу реализовать. Я включил то, что должно быть легко компилировать и полностью продемонстрировать реализацию. Удачи.
main.cpp демонстрирует использование.
#include "Reader.h"
#include "Reader_Async_Wrapper.h"
using namespace std;
int main() {
Reader *reader = new Reader("test");
Reader_Async_Wrapper async_reader(reader);
int img_index=0;
char* data;
data = async_reader.get_data();
while(((int*)data)[0]!=-1){
cout<<"processing image "<<img_index<<endl;
sleep(2);
cout<<"processed image "<<img_index++<<endl;
delete[] data;
data = async_reader.get_data();
}
return 0;
}
Reader.h простой последовательно реализован файл ввода/вывода класса
#include <iostream>
#include <fstream>
#include <unistd.h>
using namespace std;
class Reader{
public:
bool isFinished(){return finished;}
Reader(string file_name){
open_file(file_name);
finished=false;
img_index=0;
}
char* read_data(){
cout<<"Reading img: "<<img_index<<endl;
sleep(1);
cout<<"Read img: "<<img_index++<<endl;
if(img_index==10)finished=true;
return new char[1000];
}
private:
bool finished;
int img_index;
void open_file(string name){
// TODO
}
};
Reader_Async_Wrapper.h является простой оболочкой для Reader.h, чтобы запустить его асинхронно
#include "Reader.h"
#include <pthread.h>
using namespace std;
class Reader_Async_Wrapper{
public:
pthread_t thread;
pthread_attr_t attr;
Reader* reader;
pthread_barrier_t barrier;
Reader_Async_Wrapper(Reader* reader):reader(reader){
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_barrier_init (&barrier, NULL, 2);
pthread_create(&thread, &attr, &Reader_Async_Wrapper::threadHelper, this);
finished=false;
image_data=NULL;
}
void finish(){
pthread_attr_destroy(&attr);
void *status;
pthread_join(thread, &status);
}
char* get_data(){
pthread_barrier_wait (&barrier);
return image_data;
}
void clear_buffer(char* old_image){
delete[] old_image;
}
private:
char* image_data;
static void *threadHelper(void * contx){
return ((Reader_Async_Wrapper *)contx)->async_loop();
}
bool finished;
void *async_loop(){
while(!finished){
if(reader->isFinished()){
finished=true;
image_data=new char[sizeof(int)];
((int*)image_data)[0]=-1;
}else
image_data=reader->read_data();
pthread_barrier_wait(&barrier);
}
pthread_exit(NULL);
return NULL;
}
};
Я бы предложил улучшить обработку, связанную с обнаружением конца файла (при условии, что вы читаете из одного длинного файла). В противном случае, я думаю, вы можете легко расширить это приложение.
Этот метод должен быть достаточным, если вы не собираетесь обрабатывать многие случаи одновременно, и в основном вы используете это как метод, чтобы скрыть задержку, связанную с чтением файла.
Если вы хотите обрабатывать многие случаи одновременно, вы можете использовать оболочку для переноса чтения и обработки файла. Что касается CUDA, я считаю, что все они должны иметь контекст CUDA.
Если вы хотите, чтобы иметь возможность обрабатывать параллельно на графическом процессоре, есть несколько вещей, которые я бы рекомендовал: Создайте несколько экземпляров класса-обертки, по одному для каждого параллельного экземпляра, который вам нужен. Выделите достаточно памяти один раз для каждого экземпляра async в конструкторе класса. Назначьте поток GPU для каждой нити, чтобы ядро могло работать параллельно. Выполняйте все копии памяти и выполнение ядра в потоке GPU.
Спасибо, что принял, было ли что-нибудь еще, что вы искали? Я заметил, что вы не голосовали. –