Мой код - это сервер извлечения функций, который должен быть многопоточным. Он использует M XNET C ++ с поддержкой GPU (cuda).
Я собрал библиотеку m xnet и провел несколько тестов, и все заработало.
Теперь возникает проблема ... Когда я писал код сервера, всякий раз, когда я выполняю извлечение функций, потребление ОЗУ графического процессора увеличивается до достижения максимума, и код падает.
мой код:
Context global_ctx(kGPU, 0);
FeatureExtractor *fe = new FeatureExtractor();
int sockfd, newsockfd, portno, pid;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi("2200");
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
int count =0;
while (1)
{
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
pthread_t thread;
ThreadData data;
data.fe = fe;
data.newsockfd = newsockfd;
data.threadNumber = count;
count ++;
pthread_create(&thread, NULL, testThread, (void*)&data);
}
close(sockfd);
Функция потока testThread:
QElapsedTimer timer;
ThreadData data = *((ThreadData*) arg);
int newsockfd = data.newsockfd;
FeatureExtractor *fe = data.fe;
int count = data.threadNumber;
int n;
char msgLen[10];
unsigned char *buffer;
bzero(msgLen, 10);
n = read(newsockfd,msgLen,10);
if (n < 0)
error("ERROR reading from socket");
int size = stoi(msgLen);
int chunk = 1024;
n = write(newsockfd,msgLen,10);
if (n < 0)
error("ERROR writing to socket");
buffer = new unsigned char [size];
int current=0;
while(current<size)
{
n = read(newsockfd,(unsigned char*)(buffer)+current, min(chunk,size-current));
if (n <= 0)
{
cout<<"ERROR reading from socket when receiving"<<endl;
break;
}
current+=n;
}
vector<unsigned char> imageBuffer(buffer, buffer + size);
Mat frame = imdecode(imageBuffer,1);
timer.start();
auto data1 = Data2NDArray(frame);
vector<float> test = fe->Extract(data1);
cout<<"done "<<count<<" in: "<<timer.elapsed()<<" ms"<<endl;
close(newsockfd);
pthread_exit(NULL);
Экстрактор функций определен как:
class FeatureExtractor {
map<string, NDArray> args_map;
map<string, NDArray> aux_map;
Symbol net;
Executor *executor;
void GetFeatureSymbol()
{
QElapsedTimer timer;
timer.start();
net = Symbol::Load("./model/model-symbol.json").GetInternals()["fc1_output"];
cout<<"Time To Load: "<<timer.elapsed()<<endl;
}
void LoadParameters() {
map<string, NDArray> paramters;
NDArray::Load("./model/model-0001.params", 0, ¶mters);
for (const auto &k : paramters)
{
if (k.first.substr(0, 4) == "aux:") {
auto name = k.first.substr(4, k.first.size() - 4);
aux_map[name] = k.second.Copy(global_ctx);
}
if (k.first.substr(0, 4) == "arg:") {
auto name = k.first.substr(4, k.first.size() - 4);
args_map[name] = k.second.Copy(global_ctx);
}
}
NDArray::WaitAll();
}
public:
FeatureExtractor()
{
GetFeatureSymbol();
LoadParameters();
}
vector<float> Extract(NDArray data) {
args_map["data"] = data;
executor = net.SimpleBind(global_ctx, args_map, map<string, NDArray>(),
map<string, OpReqType>(), aux_map);
executor->Forward(false);
auto array = executor->outputs[0].Copy(Context(kCPU, 0));
NDArray::WaitAll();
array = array.Reshape({1, 512});
double mod = 0.0;
for (size_t i = 0; i < 512; ++i)
{
mod += array.At(0,i) * array.At(0,i);
}
double mag = std::sqrt(mod);
vector<float> output;
for (size_t i = 0; i < 512; ++i)
{
output.push_back(array.At(0, i) / mag);
}
executor->Backward();
delete executor;
return output;
}
};
Я перешел в режим отладки и обнаружил, что в этой строке происходит увеличение памяти графического процессора
executor = net.SimpleBind(global_ctx, args_map, map<string, NDArray>(),
map<string, OpReqType>(), aux_map);
Я удаляю исполнителя, но память (показанная в nvidia-smi) не освобождается. Я пропустил немного свободного, немного памяти, которая должна быть очищена на GPU ...