I decided to created a new thread for a strange problem which is related to using #pragma prefetch on STL container std::vector. During the compilation phase ICC 14 disables #pragma prefetch directives which are declared on vector container. I must admit that in case of C-style array aferomentioned pragmas are "accepted" by the Compiler. Theoretically I could have relied more on HW Prefetch because of predictable linear access of vector elements, but I wanted to tune a little prefetch distance by manually inserting #pragma directives and run performance tests on various configuration values. I am not sure if OpenMP pragmas could be somehow responsible for disabling prefetch pragmas.
Few explanations related to design question and usage of STL vector instead of C-style arrays.
I based the design of Radar Signals polymorphic classes on STL containers because I would like to minimize as much as possible the usage of raw pointers allocated by operator new hence the choice of vector. In my case #pragma prefetch was inserted before single for loop with number of iterations known at compile time. Data access was linearly incremented without any dependencies on previous or next vector element. In my example vector is being read by its operator subscript so it behaves like plain array.
Thanks in advance for any help.
Here is a code snippet which demonstrates this issue. #pragma prefetch directives are commented out.
@Brief: Computes signal IQ Decomposition. @Params: _Inout_ vector to be initialized with IQ decomposed ExpChirpSignal , _In_ number of threads. @Returns: by argument std::vector<std::pair<double,double>> IQ initialized with ExpChirpSignal IQ decomposition. @Throws: std::runtime_error when n_threads argument is <= 0, or when or when vector<std::pair<double,double>> IQ is empty. */ _Raises_SEH_exception_ void radiolocation::ExpChirpSignal::quadrature_components_extraction(_Inout_ std::vector<std::pair<double, double>> &IQ, _In_ const int n_threads) { #if defined _DEBUG _ASSERTE(0 <= n_threads); #else if (n_threads <= 0) BOOST_THROW_EXCEPTION( invalid_value_arg() << boost::errinfo_api_function("ExpChirpSignal::quadrature_components_extraction") << boost::errinfo_errno(errno) << boost::errinfo_at_line(__LINE__)); #endif if (!(IQ.empty())) { size_t a_samples = this->m_samples; std::vector<double> a_cos_part(a_samples); std::vector<double> a_sin_part(a_samples); std::vector<double> a_phase(this->m_phase); std::vector<std::pair<double, double>> a_chirp(this->m_chirp); double a_efreq = this->m_efrequency; double a_timestep = this->m_init_time; double a_interval = this->m_interval; size_t i; double inv_samples{ 1.0 / static_cast<double>(a_samples) }; double delta{ 0.0 }; double t{ 0.0 }; omp_set_num_threads(n_threads); #if defined OMP_TIMING double start{ wrapp_omp_get_wtime() }; #endif // Prefetching distances should be tested in order to find an optimal distance. // ICC 14 upon compiling these pragma statements classifies them as a warning and disables them // I suppose that the culprit is related to usage of std::vector. /*#pragma prefetch a_cos_part:0:4 #pragma prefetch a_cos_part:1:32 #pragma prefetch a_sin_part:0:4 #pragma prefetch a_sin_part:1:32*/ #pragma omp parallel for default(shared) schedule(runtime) \ private(i, delta, t) reduction(+:a_timestep) for (i = 0; i < a_samples; ++i) { a_timestep += a_interval; delta = static_cast<double>(i)* inv_samples; t = a_timestep * delta; a_cos_part.operator[](i) = 2.0 * ::cos((TWO_PI * a_efreq * t) + a_phase.operator[](i)); a_sin_part.operator[](i) = -2.0 * ::sin((TWO_PI * a_efreq * t) + a_phase.operator[](i)); IQ.operator[](i).operator=({ a_chirp.operator[](i).second * a_cos_part.operator[](i), a_chirp.operator[](i).second * a_sin_part.operator[](i) }); } #if defined OMP_TIMING double end{ wrapp_omp_get_wtime() }; std::printf("ExpChirpSignal::quadrature_components_extraction executed in:%.15fseconds\n", end - start); #endif } else BOOST_THROW_EXCEPTION( empty_vector() << boost::errinfo_api_function("ExpChirpSignal::quadrature_components_exception") << boost::errinfo_errno(errno) << boost::errinfo_at_line(__LINE__)); }