获取分配内存的特定长度的一部分space
Get part of specific length of allocated memory space
我使用 malloc()
将数十亿位加载到 RAM 中 - 将其称为 big_set。我在 RAM 中还有另外一些位(称之为 small_set),它们都设置为 1,我知道它的大小(多少位——我称之为 ss_size),但无法预测,因为每次执行都会有所不同。 ss_size有时小到100,大到数亿。
我需要在 small_set 和 [=] 的某些 不可预测的 部分之间做一些按位运算ss_size 位长度的 73=]。我不能只扩展 small_set 在最重要和最不重要的两边都用零来使其大小等于 big_set 的大小,因为那将是非常大的 RAM 并且 CPU 昂贵(相同的操作将同时完成许多不同大小的 small_set s 并且还将在 small_set 上进行移位操作,扩展它会导致更多位 CPU 继续工作)。
示例:
big_set: 100111001111100011000111110001100
(实际是十亿位)
small_set: 111111
, 所以 ss_size 是 6.(可能是一个不可预测的位数)。
我需要取 big_set 的 6 位长度部分,例如:001100
、000111
等。观察:不是必须是第 N 个 6 位,例如,它可以是从第 3 位到第 9 位。不知道怎么弄。
我不想得到一个 big_set 副本,除了我要采用的 6 位之外,所有内容都归零,例如 000000001111100000000000000000000
,因为那也会非常昂贵的 RAM。
问题是:如何从 big_set 中的任何位置获取 N 位,以便我可以在它们与 [= 之间进行按位运算74=]?正 N = ss_size.
我不确定下面给出的示例是否能回答您的问题,我也不确定实现的 XOR 是否能正常工作。
但我试图展示如果任务是节省内存,算法的实现会有多混乱。
这是我在 big_set
中 40 位和 small_set
中 6 位的示例:
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
void setBitsInMemory(uint8_t * memPtr, size_t from, size_t to)
// sets bits in the memory allocated from memPtr (pointer to the first byte)
// where from and to are numbers of bits to be set
{
for (size_t i = from; i <= to; i++)
{
size_t block = i / 8;
size_t offset = i % 8;
*(memPtr + block) |= 0x1 << offset;
}
}
uint8_t * allocAndBuildSmallSet(size_t bitNum)
// Allocate memory to store bitNum bits and set them to 1
{
uint8_t * ptr = NULL;
size_t byteNum = 1 + bitNum / 8; // determine number of bytes for
ptr = (uint8_t*) malloc(byteNum);
if (ptr != NULL)
{
for (size_t i = 0; i < byteNum; i++) ptr[i] = 0;
setBitsInMemory(ptr, 0, bitNum - 1);
}
return ptr;
}
void printBits(uint8_t * memPtr, size_t from, size_t to)
{
for (size_t i = from; i <= to; i++)
{
size_t block = i / 8;
size_t offset = i % 8;
if (*(memPtr + block) & (0x1 << offset) )
printf("1");
else
printf("0");
}
}
void applyXOR(uint8_t * mainMem, size_t start, size_t cnt, uint8_t * pattern, size_t ptrnSize)
// Applys bitwise XOR between cnt bits of mainMem and pattern
// starting from start bit in mainMem and 0 bit in pattern
// if pattern is smaller than cnt, it will be applyed cyclically
{
size_t ptrnBlk = 0;
size_t ptrnOff = 0;
for (size_t i = start; i < start + cnt; i++)
{
size_t block = i / 8;
size_t offset = i % 8;
*(mainMem + block) ^= ((*(pattern + ptrnBlk) & (0x1 << ptrnOff)) ? 1 : 0) << offset;
ptrnOff++;
if ((ptrnBlk * 8 + ptrnOff) >= ptrnSize)
{
ptrnBlk = 0;
ptrnOff = 0;
}
if (ptrnOff % 8 == 0)
{
ptrnBlk++;
ptrnOff = 0;
}
}
}
int main(void)
{
uint8_t * big_set;
size_t ss_size;
uint8_t * small_set;
big_set = (uint8_t*)malloc(5); // 5 bytes (40 bit) without initialization
ss_size = 6;
small_set = allocAndBuildSmallSet(ss_size);
printf("Initial big_set:\n");
printBits(big_set, 0, 39);
// some operation for ss_size bits starting from 12th
applyXOR(big_set, 12, ss_size, small_set, ss_size);
// output for visual analysis
printf("\nbig_set after XOR with small_set:\n");
printBits(big_set, 0, 39);
printf("\n");
// free memory
free(big_set);
free(small_set);
}
在我的电脑上,我可以看到以下内容:
我使用 malloc()
将数十亿位加载到 RAM 中 - 将其称为 big_set。我在 RAM 中还有另外一些位(称之为 small_set),它们都设置为 1,我知道它的大小(多少位——我称之为 ss_size),但无法预测,因为每次执行都会有所不同。 ss_size有时小到100,大到数亿。
我需要在 small_set 和 [=] 的某些 不可预测的 部分之间做一些按位运算ss_size 位长度的 73=]。我不能只扩展 small_set 在最重要和最不重要的两边都用零来使其大小等于 big_set 的大小,因为那将是非常大的 RAM 并且 CPU 昂贵(相同的操作将同时完成许多不同大小的 small_set s 并且还将在 small_set 上进行移位操作,扩展它会导致更多位 CPU 继续工作)。
示例:
big_set: 100111001111100011000111110001100
(实际是十亿位)
small_set: 111111
, 所以 ss_size 是 6.(可能是一个不可预测的位数)。
我需要取 big_set 的 6 位长度部分,例如:001100
、000111
等。观察:不是必须是第 N 个 6 位,例如,它可以是从第 3 位到第 9 位。不知道怎么弄。
我不想得到一个 big_set 副本,除了我要采用的 6 位之外,所有内容都归零,例如 000000001111100000000000000000000
,因为那也会非常昂贵的 RAM。
问题是:如何从 big_set 中的任何位置获取 N 位,以便我可以在它们与 [= 之间进行按位运算74=]?正 N = ss_size.
我不确定下面给出的示例是否能回答您的问题,我也不确定实现的 XOR 是否能正常工作。
但我试图展示如果任务是节省内存,算法的实现会有多混乱。
这是我在 big_set
中 40 位和 small_set
中 6 位的示例:
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
void setBitsInMemory(uint8_t * memPtr, size_t from, size_t to)
// sets bits in the memory allocated from memPtr (pointer to the first byte)
// where from and to are numbers of bits to be set
{
for (size_t i = from; i <= to; i++)
{
size_t block = i / 8;
size_t offset = i % 8;
*(memPtr + block) |= 0x1 << offset;
}
}
uint8_t * allocAndBuildSmallSet(size_t bitNum)
// Allocate memory to store bitNum bits and set them to 1
{
uint8_t * ptr = NULL;
size_t byteNum = 1 + bitNum / 8; // determine number of bytes for
ptr = (uint8_t*) malloc(byteNum);
if (ptr != NULL)
{
for (size_t i = 0; i < byteNum; i++) ptr[i] = 0;
setBitsInMemory(ptr, 0, bitNum - 1);
}
return ptr;
}
void printBits(uint8_t * memPtr, size_t from, size_t to)
{
for (size_t i = from; i <= to; i++)
{
size_t block = i / 8;
size_t offset = i % 8;
if (*(memPtr + block) & (0x1 << offset) )
printf("1");
else
printf("0");
}
}
void applyXOR(uint8_t * mainMem, size_t start, size_t cnt, uint8_t * pattern, size_t ptrnSize)
// Applys bitwise XOR between cnt bits of mainMem and pattern
// starting from start bit in mainMem and 0 bit in pattern
// if pattern is smaller than cnt, it will be applyed cyclically
{
size_t ptrnBlk = 0;
size_t ptrnOff = 0;
for (size_t i = start; i < start + cnt; i++)
{
size_t block = i / 8;
size_t offset = i % 8;
*(mainMem + block) ^= ((*(pattern + ptrnBlk) & (0x1 << ptrnOff)) ? 1 : 0) << offset;
ptrnOff++;
if ((ptrnBlk * 8 + ptrnOff) >= ptrnSize)
{
ptrnBlk = 0;
ptrnOff = 0;
}
if (ptrnOff % 8 == 0)
{
ptrnBlk++;
ptrnOff = 0;
}
}
}
int main(void)
{
uint8_t * big_set;
size_t ss_size;
uint8_t * small_set;
big_set = (uint8_t*)malloc(5); // 5 bytes (40 bit) without initialization
ss_size = 6;
small_set = allocAndBuildSmallSet(ss_size);
printf("Initial big_set:\n");
printBits(big_set, 0, 39);
// some operation for ss_size bits starting from 12th
applyXOR(big_set, 12, ss_size, small_set, ss_size);
// output for visual analysis
printf("\nbig_set after XOR with small_set:\n");
printBits(big_set, 0, 39);
printf("\n");
// free memory
free(big_set);
free(small_set);
}
在我的电脑上,我可以看到以下内容: