2016-06-08 4 views
0

Я использую intrinsics для ускорения запуска кода openCV. Но после того, как я заменил код Intrinsics, стоимость исполнения кода почти одинакова или, может быть, даже хуже. я не могу понять, что и почему это происходит. Я долгое время искал этот вопрос, но отмечал изменения. Понятно, если кто-то может мне помочь. Большое спасибо! Вот мой кодкод не ускоряется при использовании Intel Intrinsics

 // if useSSE is true,run the code with intrinsics and takes 1.45ms in my computer 
     // and if not run the general code and takes the same time. 
    cv::Mat<float> results(shape.rows,2); 
    if (useSSE) { 
     float* pshape = (float*)shape.data; 
     results = shape.clone(); 
     float* presults = (float*)results.data; 
     // use SSE 
     __m128 xyxy_center = _mm_set_ps(bbox.center_y, bbox.center_x, bbox.center_y, bbox.center_x); 

     float bbox_width = bbox.width/2; 
     float bbox_height = bbox.height/2; 
     __m128 xyxy_size = _mm_set_ps(bbox_height, bbox_width, bbox_height, bbox_width); 
     gettimeofday(&start, NULL); // this is for counting time 

     int shape_size = shape.rows*shape.cols; 
     for (int i=0; i<shape_size; i +=4) { 
      __m128 a = _mm_loadu_ps(pshape+i); 
      __m128 result = _mm_div_ps(_mm_sub_ps(a, xyxy_center), xyxy_size); 
      _mm_storeu_ps(presults+i, result); 
     } 
    }else { 
     //SSE TO BE DONE 
     for (int i = 0; i < shape.rows; i++){ 
      results(i, 0) = (shape(i, 0) - bbox.center_x)/(bbox.width/2.0); 
      results(i, 1) = (shape(i, 1) - bbox.center_y)/(bbox.height/2.0); 
     } 
    } 
    gettimeofday(&end, NULL); 
    diff = 1000000*(end.tv_sec-start.tv_sec)+end.tv_sec-start.tv_usec; 
    std::cout<<diff<<"-----"<<std::endl; 
    return results; 
+3

Код _working_ может помочь вам получить ответ. Посмотрите, как это сделать [mcve] – Miki

+1

Кроме того, вам следует описать, что делает ваш код. – Catree

+2

Вам действительно нужен 'div_ps', или он может умножаться на ответ? – harold

ответ

1
  1. Ваша оптимизация SSE будет коррумпированные памяти вблизи приводит переменный, если shape.rows% 2 == 1
  2. Старайтесь избегать использования переменного я в цикле, используйте указатели непосредственно. Компилятор может оптимизировать дополнительную операцию плюс, а может и нет.
  3. Использование умножения вместо деления:

    float bbox_width_inv = 2./bbox.width; 
    float bbox_height_inv = 2./bbox.height; 
    __m128 xyxy_size = _mm_set_ps(bbox_height, bbox_width, bbox_height, bbox_width); 
    float* p_shape_end = p_shape + shape.rows*shape.cols; 
    float* p_shape_end_batch = p_shape + shape.rows*shape.cols & (~3); 
    for (; p_shape<p_shape_end_batch; p_shape+=4, presults+=4) { 
        __m128 a = _mm_loadu_ps(pshape); 
        __m128 result = _mm_mul_ps(_mm_sub_ps(a, xyxy_center), xyxy_size_inv); 
        _mm_storeu_ps(presults, result); 
    } 
    while (p_shape < p_shape_end) { 
        presults++ = (p_shape++ - bbox.center_x) * bbox_width_inv; 
        presults++ = (p_shape++ - bbox.center_y) * bbox_height_inv; 
    } 
    
  4. Попробуйте разобрать код, сгенерированный из встроенных функций, и убедитесь, что имеется достаточное количество регистров для выполнения ваших операций, и он не хранит временные результаты в ОЗУ
+0

Спасибо за все советы, которые вы мне дали! Для первого, shape.rows 2 по умолчанию и извините, я не дал понять. Для других я пробовал эти улучшения, но это не влияет на результат работы. – JochimYoung

+0

Изменение разделения на умножение не помогло? – taarraas

+0

Nop ... да, это очень странно – JochimYoung

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