Чтобы при -O3 нормально работала мне придется менять часть кода или установить дополнительные пакеты? Что я могу сделать? В кратце, моя задача такова:
Методом Гаусса-Жордана решить СЛУ(Ax = b). Для начало я распределяю матрицу A по тредам (блоками строк), т.е. каждый тред должен будет обрабатывать кусок матрицы начиная только с некоторого номера(row_start) по некоторый row_end. Моя функция work (функция, которую должен проделать каждый тред)  прогоняет цикл по i номерам строк, и если эта строка лежит в куске матрицы действующего треда, то делит на a[i][i] и т.д.
Код:
void *work (void *ptr)
{
   ARGS * arg = (ARGS*) ptr;
   int   thrN = arg->thread_number,
      rs = arg->rs,
      re = arg->re,
      n = arg->n;   
   int total_threads = arg->thread_count;
   
   double *a = arg->a,
          *b = arg->b;
          
   double tmp;
   
   int i, k, j;
   for (i = 0; i < n; i++)
   {
      if (i <= re && i >= rs)
      {
         tmp = a[i*n + i];
         for (k = i; k < n; k++)
            a[i*n + k] /= tmp;
         b[i] /= tmp;        
      }
      synchronize(total_threads);
      if (i <= re && i >= rs)
      {
         for (j = rs; j < i; j++)
         {
            tmp = a[j * n + i];
            
            for (k = i; k < n; k++)
               a[j*n + k] -= a[i*n + k] * tmp;
            b[j] -= b[i] * tmp;
         }
         for (j = i + 1; j <= re; j++)
         {
            tmp = a[j * n + i];
            for (k = i; k < n; k++)
               a[j*n + k] -= a[i*n + k] * tmp;
            b[j] -= b[i] * tmp;
         }
      }
      else
      {
         for (j = rs; j <= re; j++)
         {
            tmp = a[j * n + i];
            for (k = i; k < n; k++)
               a[j*n + k] -= a[i*n + k]*tmp;
            
            b[j] -= b[i] * tmp;
         }
      }
   }
   
   return NULL;
} 
Как я понимаю, чем меньше synchronize, тем быстрее работает распараллеливание. Как видите, использую sync только в одном месте. Мне кажется, это самый оптимальный вариант. Не так ли?