Cpp Basics - ashBabu/Utilities GitHub Wiki
std::execution::par
, works mainly for STL
#include <iostream>
#include <execution>
#include <vector>
int main()
{
std::vector<int> v{1, 22, 54, 87, 56, 98};
std::sort(std::execution::par, v.begin(), v.end());
return 0;
}
check out std::async()
, std::future
Thread building blocks (TBB)
sudo apt install libtbb-dev
- Example
#include <iostream>
#include <vector>
#include <tbb/tbb.h>
#include <chrono>
int summarize(const std::vector<int>& vec) {
int sum = 0;
for (int i = 0; i < vec.size(); ++i) {
sum += vec[i];
}
return sum;
}
int summarize_tbb(const std::vector<int>& vec)
{
// Parallel summation using TBB
int sum = tbb::parallel_reduce(
tbb::blocked_range<std::size_t>{0, vec.size()}, // Range of indices to process
0, // Initial value for local sums
[&vec] (const auto& r, int init)
{
for (auto i = r.begin(); i != r.end(); ++i)
{
init += vec[i];
}
return init;
},
std::plus<int>{}
);
// Another way
/*
// Parallel summation using TBB
tbb::parallel_reduce(
tbb::blocked_range<size_t>(0, N), // Range of indices to process
0, // Initial value for local sums
[&](const tbb::blocked_range<size_t>& range, int local_sum) -> int {
for (size_t i = range.begin(); i < range.end(); ++i) {
local_sum += numbers[i];
}
return local_sum;
},
[](int x, int y) -> int {
return x + y; // Combine local sums into the final result
});
*/
return sum;
}
int main() {
// Create a large vector with numbers from 1 to 1,000,000
const size_t N = 1'000'000;
std::vector<int> numbers(N);
for (size_t i = 0; i < N; ++i) {
numbers[i] = i + 1;
}
// Variable to store the result
auto start = std::chrono::steady_clock::now();
int sum_result = summarize(numbers);
auto end = std::chrono::steady_clock::now();
auto duration = end - start;
std::cout<< "The sum is "<< sum_result<< " and the time taken for normal summation is "<< duration.count() <<"\n";
start = std::chrono::steady_clock::now();
int sum_tbb = summarize_tbb(numbers);
end = std::chrono::steady_clock::now();
duration = end - start;
std::cout<< "The sum is "<< sum_result<< " and the time taken for tbb summation is "<< duration.count() <<"\n";
return 0;
}
- CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(tbb)
# find dependencies
find_package(TBB REQUIRED)
include_directories(
include
)
add_executable(tbb
tbb.cpp
)
target_link_libraries(tbb PRIVATE TBB::tbb)
- Result
The sum is 1784293664 and the time taken for normal summation is 5289687
The sum is 1784293664 and the time taken for tbb summation is 2713345
- Tutorial
- Basic structure is
[capture_clause](params){function_definition}
- Example
#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
int d=7, e=5;
std::vector<int> v{2, 5, 8, 25, 77};
std::for_each(v.begin(), v.end(), [](int x){std::cout<<x<<"\n"}); // just prints out all the numbers in v
std::for_each(v.begin(), v.end(), [d](int x){
if (x%d == 0}
std::cout<<x<<" is divisible by "<<d<<"\n";
else
std::cout<<x<<" is not divisible by "<<d<<"\n";
); // d is accessible but cannot be changed inside the function
std::for_each(v.begin(), v.end(), [&d](int x){
if (x%d == 0}
std::cout<<x<<" is divisible by "<<d<<"\n";
else
std::cout<<x<<" is not divisible by "<<d<<"\n";
d = 10;
); // d is accessible and can be changed inside the function
}
-
[&d](){}
lets you changed
inside function -
[&d, &e](){}
for access and change to bothd
ande
(pass by reference) -
[&d, e](){}
for access and change tod
and but cant changee
-
[&](){}
for access and change to all variables inside the scope -
[=](){}
for access to all variables inside the scope
- Prefer
\n
overstd::endl
when outputting text to the console.
Most Preferred: List initialization, int d {5}
In C++ 17, maybe_unused
is allowed to suppress unused variable warning
int main()
{
[[maybe_unused]] double pi { 3.14159 };
[[maybe_unused]] double gravity { 9.8 };
[[maybe_unused]] double phi { 1.61803 };
std::cout << pi << '\n';
std::cout << phi << '\n';
// The compiler will no longer warn about gravity not being used
return 0;
}
The difference is that a static library will generate a copy each time it is called, and the shared library has only one copy, which saves space. Create a file src/hello_ash_lib.cpp
.
#include<iostream>
void print()
{
std::cout<<"Hello_Ash "<<std::endl;
}
-
In
CMakeLists.txt
,* add_library(hello_ash SHARED src/hello_ash_lib.cpp) will generate a `libhello_ash.so` shared library * add_library(hello_ash src/hello_ash_lib.cpp) will generate a `libhello_ash.a` static library
-
To make an executable with the above library, add the following in
CMakeLists.txt
,* add_executable(chp1 src/main.cpp) * target_link_libraries(chp1 hello_ash)
cmake .. -DCMAKE_INSTALL_PREFIX=/path/to/install/dir
- First get the path of the executable directory. A good tutorial is provided here which gives the path as
/path/to/myBinaryFile
- The following function strips the
myBinaryFile
part and gives the path to the directory/path/to/
#include <unistd.h>
#include <limits.h>
#include <string>
std::string getExePath()
{
char result[ PATH_MAX ];
ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
std::string path = std::string( result, (count > 0) ? count : 0 );
std::string::size_type pos = path.find_last_of("\\/");
return path.substr(0, pos);
}
- Use
INSTALL
inCMakeLists.txt
to add the path to yaml etc. For example,
install(TARGETS HAILaser_datafusion_app
DESTINATION "${CMAKE_INSTALL_PREFIX}/bin/")
install(DIRECTORY "${CMAKE_SOURCE_DIR}/tests/config/"
DESTINATION "${CMAKE_INSTALL_PREFIX}/bin/datafusion_app/yaml_configs/"
FILES_MATCHING PATTERN "*.yaml" # only the yamls
)
int main(int argc, char *argv[])
{
std::string current_directory = getExePath();
std::cout<<"THE CURRENT WORKING DIRECTORY is"<< current_directory << std::endl;
std::string path_to_yaml = current_directory + "/datafusion_app/yaml_configs/HDF_RAW_V2.yaml";
std::cout<<"PATH TO YAML IS: " << path_to_yaml<<std::endl;
}
Notes from A Tour of C++
-
const
does runtime checking whileconstexpr
does compile time checking - use error checks like
std::assert(p!=nullptr)
orstd::static_assert(speed>max_speed, "cant go that fast")
Available here
1. Build explanation
cmake -S . -B build
cmake --build build
cmake --build build -t test
2. Write first CMakeLists.txt explanation
cmake_minimum_required(VERSION 3.15...3.21)
project(MyProject
VERSION
1.0
DESCRIPTION
"Very nice project"
LANGUAGES
CXX
)
add_executable(myexample simple.cpp)
sudo apt install cmake-curses-gui
-
For custom packages which are built using the command
sudo make install
, the package name to be used infind_package(pkg_name REQUIRED)
may not be obvious. It should generate a file under<install-path>/lib/cmake/<package-name>
called something like<package-name>Config.cmake
-
cmake -S /path_to_src -B /path_to_build_dir
# -S is source directory where the CMakeLists.txt is and -B path to the build folder
Extract the contents and change in the directory
./configure
make
sudo make install
sudo ldconfig
OR
for example
git clone https://gitlab.com/libeigen/eigen.git
cd eigen
mkdir build
cd build
cmake ..
make install DESTDIR=/path/to/your/destination
OR sudo make install
-
sudo apt-get install cmake
# may not be the latest
- Download the latest
.tar.gz
version from here cd $CMAKE_DOWNLOAD_PATH
./configure
make
sudo make install
- Might have to reboot
OR
wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | gpg --dearmor - | sudo tee /etc/apt/trusted.gpg.d/kitware.gpg >/dev/null
-
sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ bionic main'
# for ubuntu 18.04sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main'
# for ubuntu 20.04 sudo apt update
sudo apt install kitware-archive-keyring
sudo rm /etc/apt/trusted.gpg.d/kitware.gpg