如何使用volatile矢量?

问题描述 投票:-1回答:1

我想要对进行排序需要多长时间进行基准测试:

#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    int n = 100000000;
    volatile vector<volatile int> vec; vec.reserve(n);
    for(int nn = n; nn > 0; nn--) vec.push_back(nn);
    sort(vec.begin(), vec.end());
}

AFAIK这里的volatile是必要的,因为否则编译器可以自由地优化掉对这个vector的写入,因为写入的内容从未使用过。因此,实际上不会进行排序。

但是,显然,这不起作用:

wtf.cc: In function ‘int main()’:
wtf.cc:8:50: error: passing ‘volatile std::vector<volatile int>’ as ‘this’ argument discards qualifiers [-fpermissive]
  volatile vector<volatile int> vec; vec.reserve(n);
                                                  ^
In file included from /usr/include/c++/7/vector:69:0,
                 from wtf.cc:1:
/usr/include/c++/7/bits/vector.tcc:65:5: note:   in call to ‘void std::vector<_Tp, _Alloc>::reserve(std::vector<_Tp, _Alloc>::size_type) [with _Tp = volatile int; _Alloc = std::allocator<volatile int>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
     vector<_Tp, _Alloc>::
     ^~~~~~~~~~~~~~~~~~~
wtf.cc:9:48: error: passing ‘volatile std::vector<volatile int>’ as ‘this’ argument discards qualifiers [-fpermissive]
  for(int nn = n; nn > 0; nn--) vec.push_back(nn);
                                                ^
In file included from /usr/include/c++/7/vector:64:0,
                 from wtf.cc:1:
/usr/include/c++/7/bits/stl_vector.h:939:7: note:   in call to ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = volatile int; _Alloc = std::allocator<volatile int>; std::vector<_Tp, _Alloc>::value_type = volatile int]’
       push_back(const value_type& __x)
       ^~~~~~~~~
wtf.cc:10:17: error: passing ‘volatile std::vector<volatile int>’ as ‘this’ argument discards qualifiers [-fpermissive]
  sort(vec.begin(), vec.end());
                 ^
In file included from /usr/include/c++/7/vector:64:0,
                 from wtf.cc:1:
/usr/include/c++/7/bits/stl_vector.h:563:7: note:   in call to ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::begin() [with _Tp = volatile int; _Alloc = std::allocator<volatile int>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<volatile int*, std::vector<volatile int> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = volatile int*]’
       begin() _GLIBCXX_NOEXCEPT
       ^~~~~
wtf.cc:10:28: error: passing ‘volatile std::vector<volatile int>’ as ‘this’ argument discards qualifiers [-fpermissive]
  sort(vec.begin(), vec.end());
                            ^
In file included from /usr/include/c++/7/vector:64:0,
                 from wtf.cc:1:
/usr/include/c++/7/bits/stl_vector.h:581:7: note:   in call to ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::end() [with _Tp = volatile int; _Alloc = std::allocator<volatile int>; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<volatile int*, std::vector<volatile int> >; typename std::_Vector_base<_Tp, _Alloc>::pointer = volatile int*]’
       end() _GLIBCXX_NOEXCEPT
       ^~~
In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
                 from /usr/include/c++/7/bits/allocator.h:46,
                 from /usr/include/c++/7/vector:61,
                 from wtf.cc:1:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::deallocate(__gnu_cxx::new_allocator<_Tp>::pointer, __gnu_cxx::new_allocator<_Tp>::size_type) [with _Tp = volatile int; __gnu_cxx::new_allocator<_Tp>::pointer = volatile int*; __gnu_cxx::new_allocator<_Tp>::size_type = long unsigned int]’:
/usr/include/c++/7/bits/alloc_traits.h:462:9:   required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::deallocate(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, std::allocator_traits<std::allocator<_Tp1> >::pointer, std::allocator_traits<std::allocator<_Tp1> >::size_type) [with _Tp = volatile int; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<volatile int>; std::allocator_traits<std::allocator<_Tp1> >::pointer = volatile int*; std::allocator_traits<std::allocator<_Tp1> >::size_type = long unsigned int]’
/usr/include/c++/7/bits/stl_vector.h:180:19:   required from ‘void std::_Vector_base<_Tp, _Alloc>::_M_deallocate(std::_Vector_base<_Tp, _Alloc>::pointer, std::size_t) [with _Tp = volatile int; _Alloc = std::allocator<volatile int>; std::_Vector_base<_Tp, _Alloc>::pointer = volatile int*; std::size_t = long unsigned int]’
/usr/include/c++/7/bits/vector.tcc:78:17:   required from ‘void std::vector<_Tp, _Alloc>::reserve(std::vector<_Tp, _Alloc>::size_type) [with _Tp = volatile int; _Alloc = std::allocator<volatile int>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
wtf.cc:8:50:   required from here
/usr/include/c++/7/ext/new_allocator.h:125:19: error: invalid conversion from ‘volatile void*’ to ‘void*’ [-fpermissive]
  ::operator delete(__p);
  ~~~~~~~~~~~~~~~~~^~~~~
In file included from /usr/include/c++/7/ext/new_allocator.h:33:0,
                 from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33,
                 from /usr/include/c++/7/bits/allocator.h:46,
                 from /usr/include/c++/7/vector:61,
                 from wtf.cc:1:
/usr/include/c++/7/new:124:6: note:   initializing argument 1 of ‘void operator delete(void*)’
 void operator delete(void*) _GLIBCXX_USE_NOEXCEPT
      ^~~~~~~~
In file included from /usr/include/c++/7/vector:60:0,
                 from wtf.cc:1:
/usr/include/c++/7/bits/stl_algobase.h: In instantiation of ‘static _Tp* std::__copy_move_backward<_IsMove, true, std::random_access_iterator_tag>::__copy_move_b(const _Tp*, const _Tp*, _Tp*) [with _Tp = volatile int; bool _IsMove = true]’:
/usr/include/c++/7/bits/stl_algobase.h:588:58:   required from ‘_BI2 std::__copy_move_backward_a(_BI1, _BI1, _BI2) [with bool _IsMove = true; _BI1 = volatile int*; _BI2 = volatile int*]’
/usr/include/c++/7/bits/stl_algobase.h:598:5:   required from ‘_BI2 std::__copy_move_backward_a2(_BI1, _BI1, _BI2) [with bool _IsMove = true; _BI1 = __gnu_cxx::__normal_iterator<volatile int*, std::vector<volatile int> >; _BI2 = __gnu_cxx::__normal_iterator<volatile int*, std::vector<volatile int> >]’
/usr/include/c++/7/bits/stl_algobase.h:668:48:   required from ‘_BI2 std::move_backward(_BI1, _BI1, _BI2) [with _BI1 = __gnu_cxx::__normal_iterator<volatile int*, std::vector<volatile int> >; _BI2 = __gnu_cxx::__normal_iterator<volatile int*, std::vector<volatile int> >]’
/usr/include/c++/7/bits/stl_algo.h:1851:8:   required from ‘void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<volatile int*, std::vector<volatile int> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’
/usr/include/c++/7/bits/stl_algo.h:1885:25:   required from ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<volatile int*, std::vector<volatile int> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’
/usr/include/c++/7/bits/stl_algo.h:1971:31:   required from ‘void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<volatile int*, std::vector<volatile int> >; _Compare = __gnu_cxx::__ops::_Iter_less_iter]’
/usr/include/c++/7/bits/stl_algo.h:4836:18:   required from ‘void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<volatile int*, std::vector<volatile int> >]’
wtf.cc:10:29:   required from here
/usr/include/c++/7/bits/stl_algobase.h:570:33: error: invalid conversion from ‘volatile void*’ to ‘void*’ [-fpermissive]
      __builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
                        ~~~~~~~~~^~~~~~
<built-in>: note:   initializing argument 1 of ‘void* __builtin_memmove(void*, const void*, long unsigned int)’
/usr/include/c++/7/bits/stl_algobase.h:570:23: error: invalid conversion from ‘const volatile void*’ to ‘const void*’ [-fpermissive]
      __builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
      ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<built-in>: note:   initializing argument 2 of ‘void* __builtin_memmove(void*, const void*, long unsigned int)’
/usr/include/c++/7/bits/stl_algobase.h: In instantiation of ‘static _Tp* std::__copy_move<_IsMove, true, std::random_access_iterator_tag>::__copy_m(const _Tp*, const _Tp*, _Tp*) [with _Tp = volatile int; bool _IsMove = true]’:
/usr/include/c++/7/bits/stl_algobase.h:386:44:   required from ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = true; _II = volatile int*; _OI = volatile int*]’
/usr/include/c++/7/bits/stl_algobase.h:422:45:   required from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = true; _II = volatile int*; _OI = volatile int*]’
/usr/include/c++/7/bits/stl_algobase.h:455:8:   required from ‘_OI std::copy(_II, _II, _OI) [with _II = std::move_iterator<volatile int*>; _OI = volatile int*]’
/usr/include/c++/7/bits/stl_uninitialized.h:101:27:   required from ‘static _ForwardIterator std::__uninitialized_copy<true>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<volatile int*>; _ForwardIterator = volatile int*]’
/usr/include/c++/7/bits/stl_uninitialized.h:134:15:   required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<volatile int*>; _ForwardIterator = volatile int*]’
/usr/include/c++/7/bits/stl_uninitialized.h:289:37:   required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<volatile int*>; _ForwardIterator = volatile int*; _Tp = volatile int]’
/usr/include/c++/7/bits/stl_vector.h:1263:35:   required from ‘std::vector<_Tp, _Alloc>::pointer std::vector<_Tp, _Alloc>::_M_allocate_and_copy(std::vector<_Tp, _Alloc>::size_type, _ForwardIterator, _ForwardIterator) [with _ForwardIterator = std::move_iterator<volatile int*>; _Tp = volatile int; _Alloc = std::allocator<volatile int>; std::vector<_Tp, _Alloc>::pointer = volatile int*; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
/usr/include/c++/7/bits/vector.tcc:73:40:   required from ‘void std::vector<_Tp, _Alloc>::reserve(std::vector<_Tp, _Alloc>::size_type) [with _Tp = volatile int; _Alloc = std::allocator<volatile int>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
wtf.cc:8:50:   required from here
/usr/include/c++/7/bits/stl_algobase.h:368:23: error: invalid conversion from ‘volatile void*’ to ‘void*’ [-fpermissive]
      __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<built-in>: note:   initializing argument 1 of ‘void* __builtin_memmove(void*, const void*, long unsigned int)’
/usr/include/c++/7/bits/stl_algobase.h:368:23: error: invalid conversion from ‘const volatile void*’ to ‘const void*’ [-fpermissive]
<built-in>: note:   initializing argument 2 of ‘void* __builtin_memmove(void*, const void*, long unsigned int)’

如果我只删除两个volatiles中的任何一个,编译器错误仍然存​​在。我必须删除两个错误停止;但是,正如我上面所说,我担心这会是错的。

如果以及如何在上述代码段中使用volatile

c++ compiler-errors stl volatile
1个回答
2
投票

如何使用volatile矢量?

您可以通过不调用任何成员函数来使用volatile限定向量。如果您打算对矢量进行排序,那么这不是一个选项。它们不能被调用,因为它们都不是挥发性合格的。

您不能将volatile限定元素类型与向量一起使用。

AFAIK这里的挥发性是必要的

这不是防止潜在优化的唯一方法。或者,您实际上可以读取已排序的向量。 (从技术上讲,编译器仍然可以替换排序,因为结果可以在编译时计算。它可能不会在实践中,并且可以通过使用运行时输入更有效地防止)。

© www.soinside.com 2019 - 2024. All rights reserved.