{"id":17246525,"url":"https://github.com/adbancroft/avr-fast-div","last_synced_at":"2025-03-26T05:25:15.544Z","repository":{"id":255407922,"uuid":"849435282","full_name":"adbancroft/avr-fast-div","owner":"adbancroft","description":"Optimized integer division for AVR hardware","archived":false,"fork":false,"pushed_at":"2024-11-03T20:41:05.000Z","size":114,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-31T07:14:11.343Z","etag":null,"topics":["avr","division","performance","speed"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/adbancroft.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-29T15:33:40.000Z","updated_at":"2024-11-03T20:38:58.000Z","dependencies_parsed_at":"2024-08-29T20:55:24.835Z","dependency_job_id":"e2f0011e-ad30-4aae-8e0a-2e429120a5a6","html_url":"https://github.com/adbancroft/avr-fast-div","commit_stats":null,"previous_names":["adbancroft/avr-fast-div"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adbancroft%2Favr-fast-div","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adbancroft%2Favr-fast-div/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adbancroft%2Favr-fast-div/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adbancroft%2Favr-fast-div/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adbancroft","download_url":"https://codeload.github.com/adbancroft/avr-fast-div/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245593823,"owners_count":20641139,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["avr","division","performance","speed"],"created_at":"2024-10-15T06:34:16.184Z","updated_at":"2025-03-26T05:25:15.520Z","avatar_url":"https://github.com/adbancroft.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build](https://github.com/adbancroft/avr-fast-div/actions/workflows/build.yml/badge.svg)](https://github.com/adbancroft/avr-fast-div/actions/workflows/build.yml)\n[![Unit Tests](https://github.com/adbancroft/avr-fast-div/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/adbancroft/avr-fast-div/actions/workflows/unit-tests.yml)\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=adbancroft_avr-fast-div\u0026metric=alert_status)](https://sonarcloud.io/summary/new_code?id=adbancroft_avr-fast-div)\n[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=adbancroft_avr-fast-div\u0026metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=adbancroft_avr-fast-div)\n\n# avr-fast-div: optimized integer division for AVR hardware\n\nThis library provides *up to* 60% improvement in run time division speed on AVR hardware. Exact speedup varies depending on data types \u0026 number ranges - see below for details (also see the [unit tests](https://github.com/adbancroft/avr-fast-div/actions/workflows/unit-tests.yml)).\n\nAs a general guideline, avr-fast-div is applicable to these operations:\n\n```\nuint32_t/uint16_t\nuint32_t/uint8_t\nint32_t/int16_t\nint32_t/int8_t\nuint16_t/uint8_t\nint16_t/int8_t\n````\n\n(or other divison operators where the dividend \u0026 divisor values fall within the ranges of the types above).\n\n**Best practice:** Use the smallest data type that can hold the required integer range \u0026 prefer unsigned where possible.   \n\n## Constraints\n\n 1. division using a signed type and unsigned type is not supported. E.g. `int16_t/uint16_t` (it's also a recipe for confusion, since C++ converts the signed integer to an unsigned one before doing the division).\n 2. There is no 64-bit support\n\n## Using the library\n\n### Installation\n\nThe library is available in both the [Arduino Library](https://www.arduino.cc/reference/en/libraries/avr-fast-div/) and [PlatformIO Library](https://registry.platformio.org/libraries/adbancroft/avr-fast-div) registries. \n\nThe library can also be cloned \u0026 included locally or included directly from GitHub (if your tooling supports it). \n\n### Code\n\n 1. `#include \u003cavr-fast-div.h\u003e`\n 2. Replace divide operations with a call to fast_div. I.e.\n     * `a / b` -\u003e `fast_div(a, b)`\n\nThe code base is compatible with all platforms: non-AVR builds compile down to the standard division operator.\n\n**Note:** if the divisor (`b`) is a [compile time constant greater than 8-bits](https://stackoverflow.com/questions/47994933/why-doesnt-gcc-or-clang-on-arm-use-division-by-invariant-integers-using-multip), you probably want to use [libdivide](https://libdivide.com/) instead.\n\nYou can reduce the amount of flash (.text segment) the library uses by defining `AFD_SMALL_TEXT`: this will reduce performance by up to 5% in some cases.\n\n## Details\n\nSince the AVR architecture has no hardware divider, all run time division is done in software by the compiler emitting a call to one of the division functions (E.g. [__udivmodsi4](https://github.com/gcc-mirror/gcc/blob/cdd5dd2125ca850aa8599f76bed02509590541ef/libgcc/config/avr/lib1funcs.S#L1615)) contained in a [runtime support library](https://gcc.gnu.org/wiki/avr-gcc#Exceptions_to_the_Calling_Convention).\n\nBy neccesity, the division functions are optimised for the general case. Combined with integer type promotion, this can result in sub-optimal division speed. E.g.\n\n```\n    uint16_t divisor = 355;    // Note: greater than UINT8_MAX\n    uint32_t dividend = 85123; // Note: greater than UINT16_MAX\n    \n    uint32_t result = dividend / divisor;  // 239U\n    // 1. Divisor is promoted to uint32_t\n    // (following C/C++ integer promotion rules)\n    // 2. __udivmodsi4() is called to divide (32/32=\u003e32 division)\n```\n\nIf the program is using a limited range of `[u]int32_t` or `[u]int16_t`, this can be sped up a lot. \n\nSpecifically, **if the divisor can be contained in a smaller type than the dividend *and* the result will fit into the smaller divisor type then we can halve the time of the division operation.**\n\nWhere possible, avr-fast-div will route division operations through functions optimized for the following operations:\n1. `uint32_t/uint16_t =\u003e uint16_t`\n2. `uint16_t/uint8_t =\u003e uint8_t`\n\nAs a result, the optimizations are most effective when the number ranges are constrained to a range smaller than the full integral type min \u0026 max values. \n\nExample\n\n  * An `unsigned long` storing time in milliseconds (the Arduino `millis()` function return type) has a range of 0 to ~1193 **hours**\n  * If the code base only tracks time for 1 hour,  the variable is artificially constrained to `[0, 3600000]`\n  * Division operations on it can be optimised when the divisor is greater than 64 (since `36000000/65\u003cUINT16_MAX`)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadbancroft%2Favr-fast-div","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadbancroft%2Favr-fast-div","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadbancroft%2Favr-fast-div/lists"}