Очень странные вещи происходят
Прежде всего я использую jni
android (если это важно)
У меня есть safe-thread
имплементация std::deque
с одно стороны в одном треде я наполняю эту очередь с другой стороны в другом треде я забираю с очереди
Я не могу понять почему метод который вытаскивает из очереди front()
берет около 200 миллисекунд на выполнение?
Имплементация очереди
#ifndef SAFE_QUEUE
#define SAFE_QUEUE
#include <queue>
#include <mutex>
#include <condition_variable>
#include "frame_manager.h"
#include <android/log.h>
#include <string>
#include <chrono>
using namespace std;
using namespace std::chrono;
namespace hello_ar
{
// A threadsafe-queue.
template<class T>
class safe_queue
{
public:
safe_queue(std::string const &name)
{
m_name = name;
}
~safe_queue()
= default;
// Add an element to the queue.
void enqueue(T t)
{
std::lock_guard<std::mutex> lock(m_mutex);
m_queue.push_back(t);
m_condition.notify_one();
}
std::string getName()
{
return m_name;
}
int getSize()
{
std::lock_guard<std::mutex> lock(m_mutex);
return static_cast<int>(m_queue.size());
}
// Get the "front"-element.
// If the queue is empty, wait till a element is avaiable.
T dequeue(bool flag)
{
high_resolution_clock::time_point t5 = high_resolution_clock::now();
T val;
{
std::unique_lock<std::mutex> lock(m_mutex);
while (m_queue.empty())
{
// release lock as long as the wait and reaquire it afterwards.
m_condition.wait(lock);
}
val = m_queue.front();
if (flag)
{
m_queue.pop_front();
}
}
return val;
}
T dequeue()
{
return dequeue(true);
}
void clear()
{
std::lock_guard<std::mutex> lock(m_mutex);
std::deque<std::shared_ptr<FrameManager>>().swap(m_queue);
}
bool empty()
{
std::lock_guard<std::mutex> lock(m_mutex);
return m_queue.empty();
}
public:
std::deque<T> m_queue;
mutable std::mutex m_mutex;
std::condition_variable m_condition;
std::string m_name;
};
}
#endi
Наполнение очереди происходит с помощью enqueue
Как я сказал есть еще другой класс и другой метод который выполняется на другом потоке и вытаскивает из очереди, что там есть.
void VideoRender::Draw(const glm::mat4 &projection_mat, //
const glm::mat4 &view_mat, //
glm::mat4 &model_mat //
)
{
if (!m_shaderProgram)
{
LOGE("shader_program is null.");
return;
}
if (m_bPauseFrameLoading)
return;
high_resolution_clock::time_point now_time = high_resolution_clock::now();
long long int delta_from_last_time = duration_cast<microseconds>(now_time - m_last_time).count();
if (!m_fifo.empty() && delta_from_last_time >= util::FRAME_INTERVAL_MSEC * 1000)
{
m_last_time = now_time;
high_resolution_clock::time_point t4 = high_resolution_clock::now();
m_FrameManager = m_fifo.m_queue.front();
long long int durationn = duration_cast<microseconds>(high_resolution_clock::now() - t4).count();
__android_log_print(ANDROID_LOG_ERROR, "front", "front %s::: %s", m_fifo.getName().c_str(), std::to_string(durationn).c_str());
m_fifo.m_queue.pop_front();
std::vector<GLfloat> const &vertices = m_FrameManager->getVertices();
std::vector<GLfloat> const &textures = m_FrameManager->getTextures();
std::vector<GLuint> const &indices = m_FrameManager->getIndices();
glDeleteTextures(1, &m_textureId);
glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_2D, m_textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, //
0, //
GL_RGB, //
m_FrameManager->getImageWidth(), //
m_FrameManager->getImageHeight(), //
0, //
GL_RGB, //
GL_UNSIGNED_BYTE, //
m_FrameManager->GetImageData().data()//
);
}
glUseProgram(m_shaderProgram);
if (m_FrameManager != nullptr)
{
glVertexAttribPointer(static_cast<GLuint>(m_attriVertices), 3, GL_FLOAT, GL_FALSE, 0, m_FrameManager->getVertices().data());
glEnableVertexAttribArray(static_cast<GLuint>(m_attriVertices));
glVertexAttribPointer(static_cast<GLuint>(m_attriUvs), 2, GL_FLOAT, GL_FALSE, 0, m_FrameManager->getTextures().data());
glEnableVertexAttribArray(static_cast<GLuint>(m_attriUvs));
glUniform2f(m_uniform_center_xy, static_cast<GLfloat>(m_centerX), static_cast<GLfloat>(m_centerY));
//---------------------------------------------
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_textureId);
glUniform1i(m_uniformTexture, 0);
model_mat = glm::rotate(model_mat, util::AXIS_ALIGNMENT, glm::vec3(1.F));
model_mat = glm::rotate(model_mat, m_modelRotation, glm::vec3(0, 0, 1));
model_mat = glm::scale(model_mat, glm::vec3(m_modelSize));
glm::mat4 mvp_mat = projection_mat * view_mat * model_mat;
glUniformMatrix4fv(m_uniformMvpMat, 1, GL_FALSE, glm::value_ptr(mvp_mat));
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(m_FrameManager->getIndices().size()), GL_UNSIGNED_INT, m_FrameManager->getIndices().data());
glBindTexture(GL_TEXTURE_2D, 0);
}
glDisableVertexAttribArray(static_cast<GLuint>(m_attriVertices));
glDisableVertexAttribArray(static_cast<GLuint>(m_attriUvs));
glUseProgram(0);
util::CheckGlError("VideoRender::Draw()");
}
Это длинный метод и на самом деле вам не нужно знать все, что здесь происходит, но я хочу обратить внимание на строку
m_FrameManager = m_fifo.m_queue.front();
Здесь я специально сделал m_queue
public чтоб убрать возможные сомнения , теперь я напрямую обращаюсь в мою имплементацию очереди от туда я напрямую беру std::deque
и уже на ней вызываю front()
, чтоб получить обьект
Так же сразу же этого метода есть следующая строка в которой я логирую время выполнения
__android_log_print(ANDROID_LOG_ERROR, "front", "front %s::: %s", m_fifo.getName().c_str(), std::to_string(durationn).c_str());
И вот время выполнения
13:03:27.137 E/front: front video_render::: 213285
13:03:27.446 E/front: front video_render::: 276841
13:03:27.710 E/front: front video_render::: 238782
13:03:27.936 E/front: front video_render::: 197096
13:03:28.171 E/front: front video_render::: 216234
13:03:28.400 E/front: front video_render::: 208742
13:03:28.620 E/front: front video_render::: 205443
13:03:28.869 E/front: front video_render::: 227723
13:03:29.117 E/front: front video_render::: 217806
13:03:29.345 E/front: front video_render::: 207497
13:03:29.575 E/front: front video_render::: 214358
13:03:29.806 E/front: front video_render::: 216148
13:03:30.006 E/front: front video_render::: 186434
13:03:30.207 E/front: front video_render::: 188939
13:03:30.414 E/front: front video_render::: 192210
13:03:30.620 E/front: front video_render::: 189335
13:03:30.821 E/front: front video_render::: 186266
13:03:31.025 E/front: front video_render::: 186589
Так что вопрос, как такое возможно, что время выполнения стандартного метода front()
200 милисекунд?
EDIT
Тип обьекта в очереди std::shared_ptr<FrameManager>
struct FrameManager
{
private:
std::vector<GLfloat> m_vertices;
std::vector<GLfloat> m_textures;
std::vector<GLuint> m_indices;
std::vector<GLuint> m_indicess;
std::vector<GLuint> m_indicesss;
std::vector<GLuint> m_indicessss;
std::vector<unsigned char> m_imageData;
GeometryLoader m_geometryLoader;
NativeCodec &m_nativeCodec;
bool m_isGeometryLoaded = false;
bool m_isTexLoaded = false;
....
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Зачем нужно пробрасывать исключения? Почему может быть нельзя из сразу обработать?
Есть WebView который подгружает локальный (хранящийся в память приложения) файл indexhtml
Я использую Spring-ws для написания SOAP-клиентаПри этом на сервере используются две wsdl для тестовой и продакшн сред, одинаковые по содержанию,...
В чем проблема? Comple error : Compilation failed; see the compiler error output for details