From: Martin Kronbichler Date: Tue, 14 Mar 2017 09:25:25 +0000 (+0100) Subject: Use vectorized gather operation if available. X-Git-Tag: v9.0.0-rc1~1768^2~5 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=107fb58144aee26b5e571057e7bbe3d75b0140d1;p=dealii.git Use vectorized gather operation if available. --- diff --git a/include/deal.II/matrix_free/fe_evaluation.h b/include/deal.II/matrix_free/fe_evaluation.h index ea77ffa148..a8e8bef3e8 100644 --- a/include/deal.II/matrix_free/fe_evaluation.h +++ b/include/deal.II/matrix_free/fe_evaluation.h @@ -2765,6 +2765,25 @@ namespace internal res = vector_access (const_cast(vec), index); } + template + void process_dof_gather (const unsigned int *indices, + VectorType &vec, + VectorizedArray &res, + internal::bool2type) const + { + res.gather(vec.begin(), indices); + } + + template + void process_dof_gather (const unsigned int *indices, + VectorType &vec, + VectorizedArray &res, + internal::bool2type) const + { + for (unsigned int v=0; v::n_array_elements; ++v) + res[v] = vector_access(const_cast(vec), indices[v]); + } + template void process_dof_global (const types::global_dof_index index, VectorType &vec, @@ -2812,6 +2831,34 @@ namespace internal vector_access (vec, index) += res; } + template + void process_dof_gather (const unsigned int *indices, + VectorType &vec, + VectorizedArray &res, + internal::bool2type) const + { +#if DEAL_II_COMPILER_VECTORIZATION_LEVEL < 3 + for (unsigned int v=0; v::n_array_elements; ++v) + vector_access(vec, indices[v]) += res[v]; +#else + // only use gather in case there is also scatter + VectorizedArray tmp; + tmp.gather(vec.begin(), indices); + tmp += res; + tmp.scatter(indices, vec.begin()); +#endif + } + + template + void process_dof_gather (const unsigned int *indices, + VectorType &vec, + VectorizedArray &res, + internal::bool2type) const + { + for (unsigned int v=0; v::n_array_elements; ++v) + vector_access(vec, indices[v]) += res[v]; + } + template void process_dof_global (const types::global_dof_index index, VectorType &vec, @@ -2858,6 +2905,25 @@ namespace internal vector_access (vec, index) = res; } + template + void process_dof_gather (const unsigned int *indices, + VectorType &vec, + VectorizedArray &res, + internal::bool2type) const + { + res.scatter(indices, vec.begin()); + } + + template + void process_dof_gather (const unsigned int *indices, + VectorType &vec, + VectorizedArray &res, + internal::bool2type) const + { + for (unsigned int v=0; v::n_array_elements; ++v) + vector_access(vec, indices[v]) = res[v]; + } + template void process_dof_global (const types::global_dof_index index, VectorType &vec, @@ -3071,11 +3137,11 @@ FEEvaluationBase // vectorization loop AssertDimension (dof_info->end_indices(cell)-dof_indices, static_cast(n_local_dofs)); - for (unsigned int j=0; j::n_array_elements) - for (unsigned int v=0; v::n_array_elements; ++v) - for (unsigned int comp=0; comp::n_array_elements) + for (unsigned int comp=0; comp::value>()); } } @@ -3214,10 +3280,11 @@ FEEvaluationBase // vectorization loop AssertDimension (dof_info->end_indices(cell)-dof_indices, static_cast(n_local_dofs)); - for (unsigned int j=0; j::n_array_elements) - for (unsigned int v=0; v::n_array_elements; ++v) - operation.process_dof (dof_indices[j+v], *src[0], - local_data[j+v]); + for (unsigned int comp=0, ind=0; comp::n_array_elements) + operation.process_dof_gather(dof_indices+ind, + *src[0], values_dofs[comp][j], + dealii::internal::bool2type::value>()); } }