Speed up by ignoring std::cout

Test Code

  1. #include <iostream>
  2.  
  3. int main(int argc, char *argv[])
  4. {
  5. 	//std::cout.setstate(std::ios_base::badbit);
  6. 	for(int i = 0; i < 100; i ++) {
  7. 		for(int i = 0; i < 100; i ++) {
  8. 			;//std::cout << "" << std::endl;
  9. 		}
  10. 	}
  11. 	return 0;
  12. }

Test it without std::cout

  1. root@imx6ul7d:~/tmp# time ./t1_1 
  2.  
  3. real    0m0.041s
  4. user    0m0.020s
  5. sys     0m0.000s

Test it with std::cout, but redirect to /dev/null

  1. root@imx6ul7d:~/tmp# time ./t1_0 > /dev/null
  2.  
  3. real    0m0.096s
  4. user    0m0.030s
  5. sys     0m0.030s

Test it with std::cout, but set io state

  1. root@imx6ul7d:~/tmp# time ./t1_2
  2.  
  3. real    0m0.061s
  4. user    0m0.040s
  5. sys     0m0.000s

Profile : Linux

Example 1

Add -pg

  1. arm-linux-gnueabihf-g++ -Wall -g -pg hello.cpp -o hello -std=c++17

Test

  1. root@imx6ul7d:~# gprof -b hello 
  2. Flat profile:
  3.  
  4. Each sample counts as 0.01 seconds.
  5.   %   cumulative   self              self     total           
  6.  time   seconds   seconds    calls   s/call   s/call  name    
  7. 100.00      3.45     3.45        1     3.45     3.45  hehe()
  8.   0.00      3.45     0.00        4     0.00     0.00  std::_Optional_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::_M_is_engaged() const
  9. ......

IPC Performance : Socket on ARM

Test Environment

CPU: Freescale i.MX6UL rev1.1 528 MHz
DRAM: 512 MiB

Test Code

  1. #include <stdlib.h>
  2. #include <sys/types.h>
  3. #include <sys/socket.h> 
  4. #include <netinet/in.h>
  5. #include <errno.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <fcntl.h>
  9.  
  10. #define CLTIP "127.0.0.1"
  11. #define SRVPORT 10172
  12. #define MAX_NUM 1024
  13.  
  14. int main(int argc, char* argv[])
  15. {
  16. 	struct timeval tv_sta, tv_end;
  17.  
  18. 	gettimeofday(&tv_sta, NULL);
  19.  
  20. 	int i = 0;
  21. 	int total = 1;
  22. 	int is_printf = 1;
  23. 	if (argc > 1) {
  24. 		total = atoi(argv[1]);
  25. 	}
  26. 	if (argc > 2) {
  27. 		is_printf = atoi(argv[2]);
  28. 	}
  29.  
  30. 	for (i = 0; i < total; i++) {
  31.  
  32. 		int clientsock = socket(PF_INET, SOCK_STREAM, 0);
  33. 		if (clientsock < 0)
  34. 		{
  35. 			printf("socket creation failed\n");
  36. 			exit(-1);
  37. 		}
  38. 		if (is_printf)
  39. 			printf("socket create successfully.\n");
  40.  
  41. 		struct sockaddr_in clientAddr;
  42. 		clientAddr.sin_family = AF_INET;
  43. 		clientAddr.sin_port = htons((u_short)SRVPORT);
  44. 		clientAddr.sin_addr.s_addr = inet_addr(CLTIP);
  45.  
  46. 		int flags = fcntl(clientsock, F_GETFL, 0);
  47. 		fcntl(clientsock, F_SETFL, flags | O_NONBLOCK);
  48.  
  49. 		int n;
  50. 		if ((n = connect(clientsock, (struct sockaddr*) & clientAddr, sizeof(struct sockaddr))) < 0)
  51. 		{
  52. 			if (errno != EINPROGRESS) {
  53. 				printf("Connect error.IP[%s], port[%d]\n", CLTIP, clientAddr.sin_port);
  54. 				exit(-1);
  55. 			}
  56. 		}
  57.  
  58. 		if (n != 0) {
  59.  
  60. 			fd_set rset, wset;
  61. 			FD_ZERO(&rset);
  62. 			FD_SET(clientsock, &rset);
  63. 			wset = rset;
  64. 			struct timeval tval;
  65. 			tval.tv_sec = 1;
  66. 			tval.tv_usec = 0;
  67. 			if ((n = select(clientsock + 1, &rset, &wset, NULL, 3 ? &tval : NULL)) == 0) {
  68. 				printf("Connect TIMEOUT.IP[%s], port[%d]\n", CLTIP, clientAddr.sin_port);
  69. 				exit(-1);
  70. 			}
  71. 			if (FD_ISSET(clientsock, &rset) || FD_ISSET(clientsock, &wset)) {
  72. 				int error;
  73. 				int len = sizeof(error);
  74. 				if (getsockopt(clientsock, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
  75. 					printf("pending error");
  76. 					exit(-1);
  77. 				}
  78. 			}
  79. 			else {
  80. 				printf("select error: clientsock not set");
  81. 				exit(-1);
  82. 			}
  83.  
  84. 		}
  85. 		fcntl(clientsock, F_SETFL, flags);
  86.  
  87. 		if (is_printf)
  88. 			printf("Connect to IP[%s], port[%d]\n", CLTIP, clientAddr.sin_port);
  89.  
  90. 		const char* sendBuf = "{\"signalType\":\"CONFIG\", \"signalData\":[{\"id\":\"CONF_NAME\", \"value\":\"PPS_MChip1\"}]}";
  91. 		char recvBuf[MAX_NUM] = { 0 };
  92.  
  93. 		//while(gets(sendBuf) != '\0')
  94. 		{
  95. 			if (send(clientsock, sendBuf, strlen(sendBuf), 0) == -1)
  96. 			{
  97. 				printf("send error!\n");
  98. 			}
  99. 			if (is_printf)
  100. 				printf("send to server:%s\n", sendBuf);
  101. 			//memset(sendBuf, 0, sizeof(sendBuf));
  102.  
  103. 			{
  104. 				int timeOut = 3000;
  105. 				int nRet = 0;
  106. 				struct timeval timeout;
  107. 				fd_set recvset;
  108. 				FD_ZERO(&recvset);
  109. 				FD_SET(clientsock, &recvset);
  110. 				timeout.tv_sec = timeOut / 1000;
  111. 				timeout.tv_usec = timeOut % 1000;
  112. 				nRet = select(clientsock + 1, &recvset, 0, 0, &timeout);
  113. 				if (nRet <= 0)
  114. 				{
  115. 					printf("clientsock recv select is error!\n");
  116. 					exit(-1);
  117. 				}
  118. 			}
  119.  
  120. 			if (recv(clientsock, recvBuf, MAX_NUM, 0) == -1)
  121. 			{
  122. 				printf("rev error!\n");
  123. 			}
  124. 			if (is_printf)
  125. 				printf("receive from server:%s\n", recvBuf);
  126. 			if (strcmp(recvBuf, "Goodbye,my dear client!") == 0)
  127. 			{
  128. 				//break;
  129. 			}
  130. 			memset(recvBuf, 0, sizeof(recvBuf));
  131. 		}
  132. 		close(clientsock);
  133.  
  134. 	}
  135.  
  136. 	gettimeofday(&tv_end, NULL);
  137.  
  138. 	int total_millisecond = (tv_end.tv_sec * 1000 + tv_end.tv_usec / 1000) - (tv_sta.tv_sec * 1000 + tv_sta.tv_usec / 1000);
  139. 	int average_millisecond = (total_millisecond / total);
  140.  
  141. 	printf("total_millisecond : %ld total_nums : %d\n", total_millisecond, total);
  142. 	printf("average_millisecond   : %ld\n", average_millisecond);
  143.  
  144. 	return 0;
  145. }

Test Result

  1. root@imx6ul7d:~/tmp# ./a.out 1 0
  2. total_millisecond : 13 total_nums : 1
  3. average_millisecond   : 13
  4. root@imx6ul7d:~/tmp# ./a.out 10 0
  5. total_millisecond : 104 total_nums : 10
  6. average_millisecond   : 10
  7. root@imx6ul7d:~/tmp# ./a.out 100 0 
  8. total_millisecond : 1023 total_nums : 100
  9. average_millisecond   : 10
  10. root@imx6ul7d:~/tmp# ./a.out 1000 0
  11. total_millisecond : 10801 total_nums : 1000
  12. average_millisecond   : 10

How to expose a local server behind a NAT or firewall to the internet

Download FRP Server & Client

Modify frps.ini

  1. [root@VM_0_5_centos frp_0.25.3_linux_amd64]# cat frps.ini
  2. [common]
  3. bind_port = xxxxxx
  4. dashboard_port = xxxxxx
  5. dashboard_user = xxxxxxxxxxxxxxxx
  6. dashboard_pwd = xxxxxxxxxxxxxxxx
  7. allow_ports = xxxxx-xxxxx
  8. token = xxxxxxxxxxxxxxxx
  9. max_pool_count = 10
  10. pool_count = 3

Start frps

  1. [root@VM_0_5_centos frp_0.25.3_linux_amd64]# ./frps -c ./frps.ini

Modify frpc.ini

  1. root@imx6ul7d:~/frp# cat frpc.ini 
  2. [common]
  3. server_addr = qinuu.com
  4. server_port = xxxxxx
  5. token = xxxxxxxxxxxxxxxx
  6. [ssh]
  7. type = tcp
  8. local_ip = 127.0.0.1
  9. local_port = 22
  10. remote_port = xxxxxx

Start frpc

root@imx6ul7d:~/frp# ./frpc -c ./frpc.ini

Start a systemd service

[root@VM_0_5_centos frp_0.25.3_linux_amd64]# cat /lib/systemd/system/frps.service
[Unit]
Description=Frp Server Service
After=network.target
 
[Service]
Type=simple
User=nobody
Restart=on-failure
RestartSec=5s
ExecStart=/usr/local/frp/frp_0.25.3_linux_amd64/frps -c /usr/local/frp/frp_0.25.3_linux_amd64/frps.ini
 
[Install]
WantedBy=multi-user.targethis
 
[root@VM_0_5_centos frp_0.25.3_linux_amd64]# systemctl start frps
[root@VM_0_5_centos frp_0.25.3_linux_amd64]# systemctl enable frps
[root@VM_0_5_centos frp_0.25.3_linux_amd64]# systemctl status frps

Cross compile wget with openssl for ARM

Config OpenSSL

tar xvf openssl-1.1.1b.tar.gz 
cd openssl-1.1.1b/
mkdir __install
./config --prefix=$PWD/__install no-asm shared

Edit Makefile

PLATFORM=linux-armv4
CROSS_COMPILE=arm-linux-gnueabihf-
delete "-m32" "-m64"

Compile OpenSSL

make
make install

Config Wget && Make

tar zxvf wget-1.20.1.tar.gz
cd wget-1.20.1
./configure --prefix=$PWD/__install --host=arm-linux CC=arm-linux-gnueabihf-gcc --with-ssl=openssl --with-libssl-prefix=/root/Downloads/wget_arm/openssl-1.1.1b/__install --without-zlib
make 
make install

./xxx: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.22′ not found (required by ./xxx)

Copy libstdc++.so.6.0.24 from cross compiler (7.3.1)

cd /usr/lib
mv libstdc++.so.6 libstdc++.so.6.bak
ln -s libstdc++.so.6.0.24 libstdc++.so.6
chmod 777 libstdc++.so.6

Now, it will be like this !

root@imx6ul7d:/usr/lib# ls -al libstdc++.so.6*
lrwxrwxrwx 1 root root      19 Sep 16 23:03 libstdc++.so.6 -> libstdc++.so.6.0.24
-rwxr-xr-x 1 root root 1240644 Sep  9 02:04 libstdc++.so.6.0.21
-rwxrwxrwx 1 root root 9459568 Sep 16 23:35 libstdc++.so.6.0.24
lrwxrwxrwx 1 root root      19 Jan  1  1970 libstdc++.so.6.bak -> libstdc++.so.6.0.21
-rwxr-xr-x 1 root root 9459568 Sep 16 23:11 libstdc++.so.6.bak_24

Some built-in macros inside CMakeSettings.json:

  • ${workspaceRoot} – provides the full path to the workspace folder
  • ${workspaceHash} – hash of workspace location; useful for creating a unique identifier for the current workspace (e.g. to use in folder paths)
  • ${projectFile} – the full path for the root CMakeLists.txt
  • ${projectDir} – the full path to the folder of the root CMakeLists.txt file
  • ${thisFile} – the full path to the CMakeSettings.json file
  • ${name} – the name of the configuration
  • ${generator} – the name of the CMake generator used in this configuration

CMake & Arm Cross compilation based Windows systems (Visual Studio)

CMakeLists.txt

  1. cmake_minimum_required(VERSION 3.12)
  2. project(network_information)
  3.  
  4. SET(CMAKE_SYSTEM_NAME Linux)
  5.  
  6. add_definitions("-std=c++17")
  7.  
  8. # specify the cross compiler
  9. SET(CMAKE_C_COMPILER   arm-linux-gnueabihf-gcc)
  10. SET(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
  11.  
  12. if(${CMAKE_HOST_SYSTEM_NAME} MATCHES "Windows")
  13.     set(BOOST_ROOT "C:/MinGW/msys/1.0/home/d/boost_1_68_0")
  14. else()
  15.     set(BOOST_ROOT /root/Downloads/boost_1_68_0)
  16. endif()
  17.  
  18. set(Boost_USE_STATIC_LIBS ON)
  19. set(Boost_USE_MULTITHREADED ON)
  20.  
  21. include_directories(sdk/inc)
  22. link_directories("sdk/lib")
  23.  
  24. add_executable(network_information
  25. 		network_information.cpp
  26. 		)
  27. TARGET_LINK_LIBRARIES(network_information "-lpthread" "-ldl" "-lpos" "-lrt" "-lpng" "-liconv" "-lfreetype" "-lz")

GNUlinux_config.cmake

  1. set(GNULINUX_PLATFORM ON)
  2. set(CMAKE_SYSTEM_NAME "Linux")
  3. set(CMAKE_SYSTEM_PROCESSOR "arm")
  4.  
  5. if(NOT DEFINED ENV{NE10_LINUX_TARGET_ARCH})
  6.    set(NE10_LINUX_TARGET_ARCH "armv7")
  7. else()
  8.    set(NE10_LINUX_TARGET_ARCH $ENV{NE10_LINUX_TARGET_ARCH})
  9. endif()
  10.  
  11. if(NE10_LINUX_TARGET_ARCH STREQUAL "armv7")
  12.    set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
  13.    set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
  14.    set(CMAKE_ASM_COMPILER arm-linux-gnueabihf-as)
  15.    find_program(CMAKE_AR NAMES "arm-linux-gnueabihf-ar")
  16.    find_program(CMAKE_RANLIB NAMES "arm-linux-gnueabihf-ranlib")
  17. elseif(NE10_LINUX_TARGET_ARCH STREQUAL "aarch64")
  18.    set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
  19.    set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
  20.    set(CMAKE_ASM_COMPILER aarch64-linux-gnu-as)
  21.    find_program(CMAKE_AR NAMES "aarch64-linux-gnu-ar")
  22.    find_program(CMAKE_RANLIB NAMES "aarch64-linux-gnu-ranlib")
  23. endif()
  24.  
  25. mark_as_advanced(CMAKE_AR)
  26. mark_as_advanced(CMAKE_RANLIB)

CMakeSettings.json

  1. {
  2.   "configurations": [
  3.     {
  4.       "environments": [
  5.         {
  6.           "MINGW64_ROOT": "C:\\MinGW\\msys\\1.0\\home\\d\\gcc-linaro-7.3.1-2018.05-i686-mingw32_arm-linux-gnueabihf",
  7.           "BIN_ROOT": "${env.MINGW64_ROOT}\\bin",
  8.           "FLAVOR": "x86_64-w64-mingw32",
  9.           "TOOLSET_VERSION": "7.3.0",
  10.           "PATH": "${env.MINGW64_ROOT}\\bin;${env.MINGW64_ROOT}\\..\\usr\\local\\bin;${env.MINGW64_ROOT}\\..\\usr\\bin;${env.MINGW64_ROOT}\\..\\bin;${env.PATH}",
  11.           "INCLUDE": "${env.INCLUDE};${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION};${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION}\\tr1;${env.MINGW64_ROOT}\\include\\c++\\${env.TOOLSET_VERSION}\\${env.FLAVOR}",
  12.           "environment": "mingw_64"
  13.         }
  14.       ],
  15.       "name": "Mingw64-Release",
  16.       "generator": "Ninja",
  17.       "configurationType": "Release",
  18.       "inheritEnvironments": [
  19.         "mingw_64"
  20.       ],
  21.       "buildRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\build\\${name}",
  22.       "installRoot": "${env.USERPROFILE}\\CMakeBuilds\\${workspaceHash}\\install\\${name}",
  23.       "cmakeCommandArgs": "",
  24.       "buildCommandArgs": "-v",
  25.       "ctestCommandArgs": "",
  26.       "intelliSenseMode": "linux-gcc-x64",
  27.       "variables": [
  28.         {
  29.           "name": "CMAKE_TOOLCHAIN_FILE",
  30.           "value": "GNUlinux_config.cmake"
  31.         },
  32.         {
  33.           "name": "CMAKE_C_COMPILER",
  34.           "value": "${env.BIN_ROOT}\\arm-linux-gnueabihf-gcc.exe"
  35.         },
  36.         {
  37.           "name": "CMAKE_CXX_COMPILER",
  38.           "value": "${env.BIN_ROOT}\\arm-linux-gnueabihf-g++.exe"
  39.         }
  40.       ]
  41.     }
  42.   ]
  43. }

Cross compile with sftp-server to ARM

zlib

  1. tar xvf zlib-1.2.11.tar.xz
  2. cd zlib-1.2.11/
  3. ./configure --prefix=/root/Downloads/sftp-server/rootfs
  4.  
  5. [root@localhost zlib-1.2.11]# diff Makefile Makefile_bak 
  6. 19c19
  7. < CC=arm-linux-gnueabihf-gcc
  8. ---
  9. > CC=gcc
  10. 30,31c30,31
  11. < LDSHARED=arm-linux-gnueabihf-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map
  12. < CPP=arm-linux-gnueabihf-gcc -E
  13. ---
  14. > LDSHARED=gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map
  15. > CPP=gcc -E
  16. 39c39
  17. < AR=arm-linux-gnueabihf-ar
  18. ---
  19. > AR=ar
  20. 41c41
  21. < RANLIB=arm-linux-gnueabihf-ranlib
  22. ---
  23. > RANLIB=ranlib
  24.  
  25. make
  26. make install

openssh

  1. tar xzf openssh-6.9p1.tar.gz 
  2. cd openssh-6.9p1/
  3. ./configure --prefix= --host=arm-linux-gnueabihf --sysconfdir=/etc --with-zlib=/root/Downloads/sftp-server/rootfs
  4. make sftp-server
  5.  
  6. [root@localhost openssh-6.9p1]# file sftp-server
  7. sftp-server: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.2.0, BuildID[sha1]=3f3bb0178b0e2ff2e27553e4754bd58d78dffd4d, not stripped