2019年11月アーカイブ

Linux memo 2019/11/22

● lz4の弱点
2016年のOSS圧縮ツール選択カタログ
https://qiita.com/nishemon/items/818cc64dc2f8577edd87
非常によく書かれた上記記事で「もはやこの分野のデファクトスタンダード」(この==速度特化型)と言わしめたlz4にも弱点があった。
lz4はデータ破損に弱く、またチェックサム類を持たないので、入力データがおかしい場合に気づきにくい。いや入力データが壊れてるとかそっちが問題だろ、というのはその通りだけど、問題とは発見されるまでは問題ではないわけで、えっとその...

● bind()のEADDRINUSEエラー
TCPサーバでbind()やlisten()がEADDRINUSEを返す場合はSO_REUSEADDRを指定できていない、というのはFAQ的だけど、これは実はサーバじゃなくても起こる。
TCPソケットにおけるTIME_WAITとSO_REUSEADDRの関係 - Qiita
https://qiita.com/bamchoh/items/1dd44ba1fbef43b5284b
短命ポートの問題は10年に一度やってくる - IGINブルネイ/syasudaの日記(MT版)
http://syasuda.com/d/blog/2019/04/10-3.html
クライアントはエフェメラルポートを使うのが通常なので踏むことが少ないけど、クライアントでポートを固定した場合に踏む。
逆に、エフェメララルポートとして使われたものもTIME_WAITになり、TIME_WAITのままサーバとしてbind(),listen()しようとするとEADDRINUSEを踏む。クライアントはSO_REUSEADDRを指定しても意味がない。素直にサーバで使うポートはip_local_reserved_portsで除外するのが正解かと。
(...と書いたもののkernelコードからの裏付けやら実テストやらがまだできてない...)
 ※ → 2019/12/22追記:実際に動かしてみて確認済み。
過去の記事(TIME_WAIT関連のメモ)もドゾ。

● TCPポートの補足
/proc/sys/net/ipv4/ip_local_port_rangeやip_local_reserved_portsは、名前に似合わずIPv6のTCPも使う。inet_csk_get_port()を使っているから。
このへんはip(7)(procfsのip_local_reserved_portsの説明)にも書かれていないっぽい?
ToDo: ipv4とipv6でTCPポートは別々に処理できる?(ポートの数を実質増やせる?)
→2019/11/27追記、Yes、ただし正確には「IPアドレスごとに処理できる」で、IPv4だけでもIPアドレスが異なれば良い。とはいえNAT環境でプライベートIPアドレス増えてもだと実質意味がないので、グローバルIPアドレスが必要かな。

● fd数上限
プロセス毎の上限は/proc/self/limitのMax open files、kernel的にはNR_FILEの8192かな?
全体の上限は/proc/sys/fs/file-max (R/W) と file-nr (R)、kernel的にはulongの最大値までいけそう?

● gccに-O2をつけ忘れないこと
gccに-O2をつけ忘れないこと。がんばって最適化したつもりでも-O2がついていないとすべてが台無しになる。...オレのがんばりをドブに捨ててたアンタのことだよ...

errno, signal, mmc's cmd, csd, ext_csd

linux/include/uapi/asm-generic/errno-base.h
linux/include/uapi/asm-generic/errno.h
linux/include/uapi/asm-generic/signal-defs.h
linux/include/linux/mmc/mmc.h
#define	EPERM		 1	/* Operation not permitted */
#define	ENOENT		 2	/* No such file or directory */
#define	ESRCH		 3	/* No such process */
#define	EINTR		 4	/* Interrupted system call */
#define	EIO		 5	/* I/O error */
#define	ENXIO		 6	/* No such device or address */
#define	E2BIG		 7	/* Argument list too long */
#define	ENOEXEC		 8	/* Exec format error */
#define	EBADF		 9	/* Bad file number */
#define	ECHILD		10	/* No child processes */
#define	EAGAIN		11	/* Try again */
#define	ENOMEM		12	/* Out of memory */
#define	EACCES		13	/* Permission denied */
#define	EFAULT		14	/* Bad address */
#define	ENOTBLK		15	/* Block device required */
#define	EBUSY		16	/* Device or resource busy */
#define	EEXIST		17	/* File exists */
#define	EXDEV		18	/* Cross-device link */
#define	ENODEV		19	/* No such device */
#define	ENOTDIR		20	/* Not a directory */
#define	EISDIR		21	/* Is a directory */
#define	EINVAL		22	/* Invalid argument */
#define	ENFILE		23	/* File table overflow */
#define	EMFILE		24	/* Too many open files */
#define	ENOTTY		25	/* Not a typewriter */
#define	ETXTBSY		26	/* Text file busy */
#define	EFBIG		27	/* File too large */
#define	ENOSPC		28	/* No space left on device */
#define	ESPIPE		29	/* Illegal seek */
#define	EROFS		30	/* Read-only file system */
#define	EMLINK		31	/* Too many links */
#define	EPIPE		32	/* Broken pipe */
#define	EDOM		33	/* Math argument out of domain of func */
#define	ERANGE		34	/* Math result not representable */
#define	EDEADLK		35	/* Resource deadlock would occur */
#define	ENAMETOOLONG	36	/* File name too long */
#define	ENOLCK		37	/* No record locks available */
#define	ENOSYS		38	/* Invalid system call number */
#define	ENOSYS		38	/* Invalid system call number */
#define	ENOTEMPTY	39	/* Directory not empty */
#define	ELOOP		40	/* Too many symbolic links encountered */
#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
#define	ENOMSG		42	/* No message of desired type */
#define	EIDRM		43	/* Identifier removed */
#define	ECHRNG		44	/* Channel number out of range */
#define	EL2NSYNC	45	/* Level 2 not synchronized */
#define	EL3HLT		46	/* Level 3 halted */
#define	EL3RST		47	/* Level 3 reset */
#define	ELNRNG		48	/* Link number out of range */
#define	EUNATCH		49	/* Protocol driver not attached */
#define	ENOCSI		50	/* No CSI structure available */
#define	EL2HLT		51	/* Level 2 halted */
#define	EBADE		52	/* Invalid exchange */
#define	EBADR		53	/* Invalid request descriptor */
#define	EXFULL		54	/* Exchange full */
#define	ENOANO		55	/* No anode */
#define	EBADRQC		56	/* Invalid request code */
#define	EBADSLT		57	/* Invalid slot */
#define	EDEADLOCK	EDEADLK
#define	EBFONT		59	/* Bad font file format */
#define	ENOSTR		60	/* Device not a stream */
#define	ENODATA		61	/* No data available */
#define	ETIME		62	/* Timer expired */
#define	ENOSR		63	/* Out of streams resources */
#define	ENONET		64	/* Machine is not on the network */
#define	ENOPKG		65	/* Package not installed */
#define	EREMOTE		66	/* Object is remote */
#define	ENOLINK		67	/* Link has been severed */
#define	EADV		68	/* Advertise error */
#define	ESRMNT		69	/* Srmount error */
#define	ECOMM		70	/* Communication error on send */
#define	EPROTO		71	/* Protocol error */
#define	EMULTIHOP	72	/* Multihop attempted */
#define	EDOTDOT		73	/* RFS specific error */
#define	EBADMSG		74	/* Not a data message */
#define	EOVERFLOW	75	/* Value too large for defined data type */
#define	ENOTUNIQ	76	/* Name not unique on network */
#define	EBADFD		77	/* File descriptor in bad state */
#define	EREMCHG		78	/* Remote address changed */
#define	ELIBACC		79	/* Can not access a needed shared library */
#define	ELIBBAD		80	/* Accessing a corrupted shared library */
#define	ELIBSCN		81	/* .lib section in a.out corrupted */
#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
#define	EILSEQ		84	/* Illegal byte sequence */
#define	ERESTART	85	/* Interrupted system call should be restarted */
#define	ESTRPIPE	86	/* Streams pipe error */
#define	EUSERS		87	/* Too many users */
#define	ENOTSOCK	88	/* Socket operation on non-socket */
#define	EDESTADDRREQ	89	/* Destination address required */
#define	EMSGSIZE	90	/* Message too long */
#define	EPROTOTYPE	91	/* Protocol wrong type for socket */
#define	ENOPROTOOPT	92	/* Protocol not available */
#define	EPROTONOSUPPORT	93	/* Protocol not supported */
#define	ESOCKTNOSUPPORT	94	/* Socket type not supported */
#define	EOPNOTSUPP	95	/* Operation not supported on transport endpoint */
#define	EPFNOSUPPORT	96	/* Protocol family not supported */
#define	EAFNOSUPPORT	97	/* Address family not supported by protocol */
#define	EADDRINUSE	98	/* Address already in use */
#define	EADDRNOTAVAIL	99	/* Cannot assign requested address */
#define	ENETDOWN	100	/* Network is down */
#define	ENETUNREACH	101	/* Network is unreachable */
#define	ENETRESET	102	/* Network dropped connection because of reset */
#define	ECONNABORTED	103	/* Software caused connection abort */
#define	ECONNRESET	104	/* Connection reset by peer */
#define	ENOBUFS		105	/* No buffer space available */
#define	EISCONN		106	/* Transport endpoint is already connected */
#define	ENOTCONN	107	/* Transport endpoint is not connected */
#define	ESHUTDOWN	108	/* Cannot send after transport endpoint shutdown */
#define	ETOOMANYREFS	109	/* Too many references: cannot splice */
#define	ETIMEDOUT	110	/* Connection timed out */
#define	ECONNREFUSED	111	/* Connection refused */
#define	EHOSTDOWN	112	/* Host is down */
#define	EHOSTUNREACH	113	/* No route to host */
#define	EALREADY	114	/* Operation already in progress */
#define	EINPROGRESS	115	/* Operation now in progress */
#define	ESTALE		116	/* Stale file handle */
#define	EUCLEAN		117	/* Structure needs cleaning */
#define	ENOTNAM		118	/* Not a XENIX named type file */
#define	ENAVAIL		119	/* No XENIX semaphores available */
#define	EISNAM		120	/* Is a named type file */
#define	EREMOTEIO	121	/* Remote I/O error */
#define	EDQUOT		122	/* Quota exceeded */
#define	ENOMEDIUM	123	/* No medium found */
#define	EMEDIUMTYPE	124	/* Wrong medium type */
#define	ECANCELED	125	/* Operation Canceled */
#define	ENOKEY		126	/* Required key not available */
#define	EKEYEXPIRED	127	/* Key has expired */
#define	EKEYREVOKED	128	/* Key has been revoked */
#define	EKEYREJECTED	129	/* Key was rejected by service */
#define	EOWNERDEAD	130	/* Owner died */
#define	ENOTRECOVERABLE	131	/* State not recoverable */
#define ERFKILL		132	/* Operation not possible due to RF-kill */
#define EHWPOISON	133	/* Memory page has hardware error */

#define _NSIG		64
#define SIGHUP		 1
#define SIGINT		 2
#define SIGQUIT		 3
#define SIGILL		 4
#define SIGTRAP		 5
#define SIGABRT		 6
#define SIGIOT		 6
#define SIGBUS		 7
#define SIGFPE		 8
#define SIGKILL		 9
#define SIGUSR1		10
#define SIGSEGV		11
#define SIGUSR2		12
#define SIGPIPE		13
#define SIGALRM		14
#define SIGTERM		15
#define SIGSTKFLT	16
#define SIGCHLD		17
#define SIGCONT		18
#define SIGSTOP		19
#define SIGTSTP		20
#define SIGTTIN		21
#define SIGTTOU		22
#define SIGURG		23
#define SIGXCPU		24
#define SIGXFSZ		25
#define SIGVTALRM	26
#define SIGPROF		27
#define SIGWINCH	28
#define SIGIO		29
#define SIGPOLL		SIGIO
#define SIGLOST		29
#define SIGPWR		30
#define SIGSYS		31
#define	SIGUNUSED	31
#define SIGRTMIN	32
#define SIGRTMAX	_NSIG

#define MMC_GO_IDLE_STATE         0   /* bc                          */
#define MMC_SEND_OP_COND          1   /* bcr  [31:0] OCR         R3  */
#define MMC_ALL_SEND_CID          2   /* bcr                     R2  */
#define MMC_SET_RELATIVE_ADDR     3   /* ac   [31:16] RCA        R1  */
#define MMC_SET_DSR               4   /* bc   [31:16] RCA            */
#define MMC_SLEEP_AWAKE		  5   /* ac   [31:16] RCA 15:flg R1b */
#define MMC_SWITCH                6   /* ac   [31:0] See below   R1b */
#define MMC_SELECT_CARD           7   /* ac   [31:16] RCA        R1  */
#define MMC_SEND_EXT_CSD          8   /* adtc                    R1  */
#define MMC_SEND_CSD              9   /* ac   [31:16] RCA        R2  */
#define MMC_SEND_CID             10   /* ac   [31:16] RCA        R2  */
#define MMC_READ_DAT_UNTIL_STOP  11   /* adtc [31:0] dadr        R1  */
#define MMC_STOP_TRANSMISSION    12   /* ac                      R1b */
#define MMC_SEND_STATUS          13   /* ac   [31:16] RCA        R1  */
#define MMC_BUS_TEST_R           14   /* adtc                    R1  */
#define MMC_GO_INACTIVE_STATE    15   /* ac   [31:16] RCA            */
#define MMC_BUS_TEST_W           19   /* adtc                    R1  */
#define MMC_SPI_READ_OCR         58   /* spi                  spi_R3 */
#define MMC_SPI_CRC_ON_OFF       59   /* spi  [0:0] flag      spi_R1 */
#define MMC_SET_BLOCKLEN         16   /* ac   [31:0] block len   R1  */
#define MMC_READ_SINGLE_BLOCK    17   /* adtc [31:0] data addr   R1  */
#define MMC_READ_MULTIPLE_BLOCK  18   /* adtc [31:0] data addr   R1  */
#define MMC_SEND_TUNING_BLOCK    19   /* adtc                    R1  */
#define MMC_SEND_TUNING_BLOCK_HS200	21	/* adtc R1  */
#define MMC_WRITE_DAT_UNTIL_STOP 20   /* adtc [31:0] data addr   R1  */
#define MMC_SET_BLOCK_COUNT      23   /* adtc [31:0] data addr   R1  */
#define MMC_WRITE_BLOCK          24   /* adtc [31:0] data addr   R1  */
#define MMC_WRITE_MULTIPLE_BLOCK 25   /* adtc                    R1  */
#define MMC_PROGRAM_CID          26   /* adtc                    R1  */
#define MMC_PROGRAM_CSD          27   /* adtc                    R1  */
#define MMC_SET_WRITE_PROT       28   /* ac   [31:0] data addr   R1b */
#define MMC_CLR_WRITE_PROT       29   /* ac   [31:0] data addr   R1b */
#define MMC_SEND_WRITE_PROT      30   /* adtc [31:0] wpdata addr R1  */
#define MMC_ERASE_GROUP_START    35   /* ac   [31:0] data addr   R1  */
#define MMC_ERASE_GROUP_END      36   /* ac   [31:0] data addr   R1  */
#define MMC_ERASE                38   /* ac                      R1b */
#define MMC_FAST_IO              39   /* ac             R4  */
#define MMC_GO_IRQ_STATE         40   /* bcr                     R5  */
#define MMC_LOCK_UNLOCK          42   /* adtc                    R1b */
#define MMC_APP_CMD              55   /* ac   [31:16] RCA        R1  */
#define MMC_GEN_CMD              56   /* adtc [0] RD/WR          R1  */
#define MMC_QUE_TASK_PARAMS      44   /* ac   [20:16] task id    R1  */
#define MMC_QUE_TASK_ADDR        45   /* ac   [31:0] data addr   R1  */
#define MMC_EXECUTE_READ_TASK    46   /* adtc [20:16] task id    R1  */
#define MMC_EXECUTE_WRITE_TASK   47   /* adtc [20:16] task id    R1  */
#define MMC_CMDQ_TASK_MGMT       48   /* ac   [20:16] task id    R1b */

#define CSD_STRUCT_VER_1_0  0           /* Valid for system specification 1.0 - 1.2 */
#define CSD_STRUCT_VER_1_1  1           /* Valid for system specification 1.4 - 2.2 */
#define CSD_STRUCT_VER_1_2  2           /* Valid for system specification 3.1 - 3.2 - 3.31 - 4.0 - 4.1 */
#define CSD_STRUCT_EXT_CSD  3           /* Version is coded in CSD_STRUCTURE in EXT_CSD */

#define EXT_CSD_CMDQ_MODE_EN		15	/* R/W */
#define EXT_CSD_FLUSH_CACHE		32      /* W */
#define EXT_CSD_CACHE_CTRL		33      /* R/W */
#define EXT_CSD_POWER_OFF_NOTIFICATION	34	/* R/W */
#define EXT_CSD_PACKED_FAILURE_INDEX	35	/* RO */
#define EXT_CSD_PACKED_CMD_STATUS	36	/* RO */
#define EXT_CSD_EXP_EVENTS_STATUS	54	/* RO, 2 bytes */
#define EXT_CSD_EXP_EVENTS_CTRL		56	/* R/W, 2 bytes */
#define EXT_CSD_DATA_SECTOR_SIZE	61	/* R */
#define EXT_CSD_GP_SIZE_MULT		143	/* R/W */
#define EXT_CSD_PARTITION_SETTING_COMPLETED 155	/* R/W */
#define EXT_CSD_PARTITION_ATTRIBUTE	156	/* R/W */
#define EXT_CSD_PARTITION_SUPPORT	160	/* RO */
#define EXT_CSD_HPI_MGMT		161	/* R/W */
#define EXT_CSD_RST_N_FUNCTION		162	/* R/W */
#define EXT_CSD_BKOPS_EN		163	/* R/W */
#define EXT_CSD_BKOPS_START		164	/* W */
#define EXT_CSD_SANITIZE_START		165     /* W */
#define EXT_CSD_WR_REL_PARAM		166	/* RO */
#define EXT_CSD_RPMB_MULT		168	/* RO */
#define EXT_CSD_FW_CONFIG		169	/* R/W */
#define EXT_CSD_BOOT_WP			173	/* R/W */
#define EXT_CSD_ERASE_GROUP_DEF		175	/* R/W */
#define EXT_CSD_PART_CONFIG		179	/* R/W */
#define EXT_CSD_ERASED_MEM_CONT		181	/* RO */
#define EXT_CSD_BUS_WIDTH		183	/* R/W */
#define EXT_CSD_STROBE_SUPPORT		184	/* RO */
#define EXT_CSD_HS_TIMING		185	/* R/W */
#define EXT_CSD_POWER_CLASS		187	/* R/W */
#define EXT_CSD_REV			192	/* RO */
#define EXT_CSD_STRUCTURE		194	/* RO */
#define EXT_CSD_CARD_TYPE		196	/* RO */
#define EXT_CSD_DRIVER_STRENGTH		197	/* RO */
#define EXT_CSD_OUT_OF_INTERRUPT_TIME	198	/* RO */
#define EXT_CSD_PART_SWITCH_TIME        199     /* RO */
#define EXT_CSD_PWR_CL_52_195		200	/* RO */
#define EXT_CSD_PWR_CL_26_195		201	/* RO */
#define EXT_CSD_PWR_CL_52_360		202	/* RO */
#define EXT_CSD_PWR_CL_26_360		203	/* RO */
#define EXT_CSD_SEC_CNT			212	/* RO, 4 bytes */
#define EXT_CSD_S_A_TIMEOUT		217	/* RO */
#define EXT_CSD_REL_WR_SEC_C		222	/* RO */
#define EXT_CSD_HC_WP_GRP_SIZE		221	/* RO */
#define EXT_CSD_ERASE_TIMEOUT_MULT	223	/* RO */
#define EXT_CSD_HC_ERASE_GRP_SIZE	224	/* RO */
#define EXT_CSD_BOOT_MULT		226	/* RO */
#define EXT_CSD_SEC_TRIM_MULT		229	/* RO */
#define EXT_CSD_SEC_ERASE_MULT		230	/* RO */
#define EXT_CSD_SEC_FEATURE_SUPPORT	231	/* RO */
#define EXT_CSD_TRIM_MULT		232	/* RO */
#define EXT_CSD_PWR_CL_200_195		236	/* RO */
#define EXT_CSD_PWR_CL_200_360		237	/* RO */
#define EXT_CSD_PWR_CL_DDR_52_195	238	/* RO */
#define EXT_CSD_PWR_CL_DDR_52_360	239	/* RO */
#define EXT_CSD_BKOPS_STATUS		246	/* RO */
#define EXT_CSD_POWER_OFF_LONG_TIME	247	/* RO */
#define EXT_CSD_GENERIC_CMD6_TIME	248	/* RO */
#define EXT_CSD_CACHE_SIZE		249	/* RO, 4 bytes */
#define EXT_CSD_PWR_CL_DDR_200_360	253	/* RO */
#define EXT_CSD_FIRMWARE_VERSION	254	/* RO, 8 bytes */
#define EXT_CSD_PRE_EOL_INFO		267	/* RO */
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A	268	/* RO */
#define EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B	269	/* RO */
#define EXT_CSD_CMDQ_DEPTH		307	/* RO */
#define EXT_CSD_CMDQ_SUPPORT		308	/* RO */
#define EXT_CSD_SUPPORTED_MODE		493	/* RO */
#define EXT_CSD_TAG_UNIT_SIZE		498	/* RO */
#define EXT_CSD_DATA_TAG_SUPPORT	499	/* RO */
#define EXT_CSD_MAX_PACKED_WRITES	500	/* RO */
#define EXT_CSD_MAX_PACKED_READS	501	/* RO */
#define EXT_CSD_BKOPS_SUPPORT		502	/* RO */
#define EXT_CSD_HPI_FEATURES		503	/* RO */

mmcは、R1,R2の意味とかmmc_switchのフォーマットとかもコメントに書かれているので、JEDEC仕様書なくてもなんとかなって、助かる(?)と思う。

ARM Cortex A性能比インチキ表

↓こんな感じのARMの資料の受け売り
ARMの次世代CPU「Cortex-A75」「Cortex-A55」は,現行CPUといったい何が違うのか
https://www.4gamer.net/games/143/G014356/20170619064/
を集めてきて真に受けた性能比を出すとこうなる。
 A55 = A53 * 1.2
 A72 = A53 * 1.7
 A73 = A72 * 1.3
 A75 = A73 * 1.3
 A76 = A75 * 1.25
 A77 = A76 * 1.2
A53を1として計算すると、
 A53 1
 A55 1.2
 A57 (まともな比較が見つからず)
 A72 1.7
 A73 2.21
 A75 2.873
 A76 3.59125
 A77 4.3095

※ さらに周波数比をかけること
※ マルチスレッド性能はコア数を考慮すること
※ 熱や消費電力で制限かかることも考慮すること
※ こんなインチキ表を当てにしないこと

Linux memo 2019/11/09

● WindowsでアプリにCPU制限させる
== やりたいこと
とあるWindows上の特殊アプリは実行すると1スレッドでぶん回って処理をする。イベントドリブンじゃなくてポーリングしてそう。不必要にCPUクロックが上がり発熱も増えファンがぶん回りバッテリがすぐ減る。困る。

== CPU binding
タスクマネジャー(Ctrl+Shift+Esc) -> 詳細 -> プロセスを選んで右クリック -> 関係の設定
2スレッド以上でぶんまわってるときは1つのCPUに閉じ込めて低減する方法が使える。が、1つのCPUは引き続きぶん回らせてしまう。
Linuxだと、taskset(1)とかsched_setaffinity(2)とか。

== 周波数の上限
電源オプション(Win+X, O) -> 電源の追加設定 -> プラン設定の変更 -> 詳細な電源設定の変更 -> プロセッサの電源管理 -> 最大のプロセッサの状態 -> %で指定
周波数の上限を設定できる。そこそこのクロックに止めれば発熱が劇的に抑えられる。が、ぶん回ってるアプリ以外の人も処理が遅くなる。
Linuxだと、/sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors でgovernorを指定し、/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freqあたり周波数を指定。ただ最近のCPUはクロックも電源管理もアグレッシブに行うので、今どきは下手に下限を固定にするのは危険かもしれない。

== 優先度
タスクマネジャー(Ctrl+Shift+Esc) -> 詳細 -> プロセスを選んで右クリック -> 優先度の設定
ぶん回るアプリと本当にCPUを使わせたいアプリとで取り合いになるのを防げる。が、アプリがぶん回ることに違いはない。
Linuxだと、renice(1)とかchrt(1)とか。

結局、LinuxのcgroupsでCPU使用率**%に制限したグループにぶん回るアプリをつっこむ、みたいなことがやりたかったわけだけど、Windows標準機能ではそういうのはなさそう。その用途だとBattle Encoder Shiraseがあるようだが、どうやって実装してんだろ。定期的に対象プロセスにptraceしてむりやりsleepさせてる感じ?

● Android System Programming
Amazonアフィリンク
Androidのミドルから下位の層をポーティングするような人向けの本として非常におすすめで、アフィで紹介すればナウでヤングにバカウケでガッポガッポ、と知り合いから聞いたので貼っとく。私はまだ買ってないけど。

● タイトル詐欺じゃね?しかも金儲けとか
いや一応Linuxのことも書いたし...

Linux memo 2019/11/07

● ARMの割り算
浮動小数点は遅かったり演算器がのってなかったりするので注意しましょう...と思っていた時期が私にもありました。
ARM Cortex-Aシリーズには、整数の割り算を行う命令がある(SDIV UDIV)が、これは最近までoptionalで、Virtualizationありのコアから必須となっている。みんな大好きCortex-A9は、たいていの場合は未対応。詳細はArm Compiler armasm User Guideあたりへ。
このため、gccで-mcpu=cortex-a9とか指定すると、gccはlibgccの中の関数(__aeabi_idiv() __aeabi_idivmod() __aeabi_uidiv() __aeabi_uidivmod())へフォールダウンするコードを吐く。...実行が遅い某プログラムのプロファイルを取って上記の名前の関数が出てきて、で調べてみて初めて知った。マジかよこいつNeonも乗ってるのに...なので、浮動小数点のほうが整数割り算より早かったりするのかもしれない。測ってないからしらんけど。
KMC Staff Blog:ARM Cortex-A15の整数除算命令
http://blog.kmckk.com/archives/4170081.html
ちなみに、Cortex-A7は対応してそう。A9からA7に乗り換えてるSoCが多いのは、プロセスノードへの対応もそうだけど、こういうとこも響いてんのかな。

● std::list<>やstd::set<>は使い物にならない?
アルゴリズム的にはstd::listやstd::setをつい使いたくなってしまうが、万とかのオーダにならない限りそこまでの差は出ない。むしろちまちました操作によるオーバヘッドのほうがでかいことも多い。
[C++] STLの型の使い分け - Qiita
https://qiita.com/h_hiro_/items/a83a8fd2391d4a3f0e1c
コンテナ内の検索の速度について - 空想犬猫記
http://xoinu.hatenablog.com/entry/2014/08/14/140105
つまり、たいていのものはstd::vector<>やstd::map<>で事足りる。
また、万とかのオーダになる場合は、どこまで最適化されたコードになるかはコンパイラやライブラリに依存することになり、古いツールチェーンだったり組み込みだったりするとロクに期待できないので、結局必要最小限に独自実装してしまいかねない。
ちなみに、入れ替えやソートをたくさん行う場合、コンテナの中身を実体で保持するとアロケートやコピーのオーバヘッドが大きくなるけど、どうするのがベストプラクティスなんだろ。個人的には、malloc,free(new,delete)の管理手間が増えるのを覚悟の上で、ポインタを保持する実装に置き換えてしまいがち。生ポにするくらいならshared_ptr<>のほうがいいんだろうけど。もちろん理想はフルにstd::moveが効くという前提で何も考えずに実体で保持するやり方のままということなんだろうけど。

● コンパイラの気持ちを考えた最適化
- グローバル変数はできるだけ使わない、使う場合もできるだけstaticつけてスコープを狭める。
- ポインタはできるだけ使わない、レファレンスなどで逃げるようにする、どうしても使わざるを得ない場合でもローカル変数に閉じてかつポインタのポインタなどを避ける。
- ローカル変数はケチらない。コンパイラのほうがうまくケチってくれる。むしろローカル変数を多用したほうがうまくコンパイラがケチってくれる。
- アラインメントとコピーサイズに注意する。char単位でちまちま処理するとたいていは遅い。memcpyの実装のアセンブリのがんばり具合を確認し、できるだけそれらに乗っかることを考えよう。
- CPUの気持ちを考えた最適化まで突っ込みたいものの、ぼく人見知りなので、CPUの個性に応じた最適化とかムリ。
- 最後に、-O2つけ忘れがないかを確認しよう。-Ogついてるだけでもかなり違う。

このアーカイブについて

このページには、2019年11月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2019年10月です。

次のアーカイブは2019年12月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

ウェブページ

Powered by Movable Type 7.9.0