Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Вычислить офсет в памяти в С. / 25 сообщений из 39, страница 1 из 2
21.04.2016, 08:56
    #39220823
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Есть внешняя память. 512 страниц. каждая страница 64 байт.
на каждой странице первые 4 байта - метка и потом 5 записей по 12 байт.
у меня есть структура в которой я записываю номер текущей страницы и номер текущей записи на странице.
нужно считать например N-ю запись от текущей. сижу думаю над алгоритмом. ничего красивого в голову не приходит. может кто подскажет интересное решение?
...
Рейтинг: 0 / 0
21.04.2016, 09:11
    #39220835
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Как-то так
Код: plaintext
1.
2.
3.
4.
5.
искомая = номер текущей записи на странице + N
if(искомая >= 5) { // на другой странице
  номер текущей страницы = номер текущей страницы + искомая / 5
  искомая = искомая % 5
} 
...
Рейтинг: 0 / 0
21.04.2016, 09:21
    #39220840
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Dima TКак-то так
Код: plaintext
1.
2.
3.
4.
5.
искомая = номер текущей записи на странице + N
if(искомая >= 5) { // на другой странице
  номер текущей страницы = номер текущей страницы + искомая / 5
  искомая = искомая % 5
} 


так мы знаем страницу а нужно знать адресс откуда считать требуемую запись.
...
Рейтинг: 0 / 0
21.04.2016, 09:27
    #39220847
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
jenya7так мы знаем страницу а нужно знать адресс откуда считать требуемую запись.
Что значит адрес? Я тебе показал как получить номер страницы и номер записи на странице. Это не адрес?

Пиши подробнее, телепатов тут нет.
...
Рейтинг: 0 / 0
21.04.2016, 09:39
    #39220855
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Dima Tjenya7так мы знаем страницу а нужно знать адресс откуда считать требуемую запись.
Что значит адрес? Я тебе показал как получить номер страницы и номер записи на странице. Это не адрес?

Пиши подробнее, телепатов тут нет.
например мы находимся на 4-ой странице 2-я запись тогда текущий адресс 192+4+12+12=220
и мы хотим получить адресс 10-ой записи от текущей 10*12 +4 +4 = 128 => 220-128= 92
у меня не получается по вашему алгоритму.
...
Рейтинг: 0 / 0
21.04.2016, 09:53
    #39220869
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
jenya7например мы находимся на 4-ой странице 2-я запись тогда текущий адресс 192+4+12+12=220
и мы хотим получить адресс 10-ой записи от текущей 10*12 +4 +4 = 128 => 220-128= 92
у меня не получается по вашему алгоритму.
Давай сначала, вот что я понял из написанного:
1. Адрес - это просто абсолютный адрес в памяти (без учета страниц и т.д.), т.е. просто указатель на структуру. Так?
2. Страницы в памяти располагаются последовательно друг за другом? Так?
3. "адрес 10-ой записи от текущей" почему "220-128" а не "220+128"? Назад чтоли смещаться надо? Всегда назад или вперед тоже надо?

ЗЫ пиши правильно: "адрес"
...
Рейтинг: 0 / 0
21.04.2016, 09:56
    #39220873
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
И распиши что ты там реально хранишь: адрес (220 в твоем примере) или страницу (4) с номером на странице (2)? От чего считать смещение?
...
Рейтинг: 0 / 0
21.04.2016, 10:06
    #39220885
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Dima Tjenya7например мы находимся на 4-ой странице 2-я запись тогда текущий адресс 192+4+12+12=220
и мы хотим получить адресс 10-ой записи от текущей 10*12 +4 +4 = 128 => 220-128= 92
у меня не получается по вашему алгоритму.
Давай сначала, вот что я понял из написанного:
1. Адрес - это просто абсолютный адрес в памяти (без учета страниц и т.д.), т.е. просто указатель на структуру. Так?
2. Страницы в памяти располагаются последовательно друг за другом? Так?
3. "адрес 10-ой записи от текущей" почему "220-128" а не "220+128"? Назад чтоли смещаться надо? Всегда назад или вперед тоже надо?

ЗЫ пиши правильно: "адрес"
да вы поняли правильно - 220 это текущий адрес - абсолютный адрес в памяти.
92 - это адрес записи которую нам нужно считать (10-я запись от последней). считывать можно только предидущие записи так как мы находимся на последней записи. впереди записей еще нет мы можем взять только записи которые уже записаны.
...
Рейтинг: 0 / 0
21.04.2016, 10:21
    #39220907
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
jenya7нужно считать например N-ю запись от текущей. сижу думаю над алгоритмом. ничего красивого в голову не приходит. может кто подскажет интересное решение?
Н-да.

Код: sql
1.
2.
3.
4.
tmp = старый_номер_записи + N;
новый_номер_страницы = старый_номер_страницы + tmp/5;
новый_номер_записи = tmp%5;
offset = 64 * новый_номер_страницы + 4 + 12 * новый_номер_записи;
...
Рейтинг: 0 / 0
21.04.2016, 10:27
    #39220914
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Так подойдет?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
#define PAGE_SIZE 64 // Размер страницы
#define HEADER_SIZE 4 // Размер заголовка страницы
#define RECORD_SIZE 12 // Размер записи

// Получение адреса новой записи по адресу текущей и смещению
int get_record(int addr, int offset) {
	int new_addr = addr - offset * RECORD_SIZE;
	while(addr / PAGE_SIZE != new_addr / PAGE_SIZE) {
		// new_addr и addr на разных страницах, корректируем 
		new_addr -= HEADER_SIZE;
		addr -= PAGE_SIZE;
	}
	return new_addr;
}


деление на 64 можно заменить на сдвиги (addr >> 6), но это компиляторы сами делают.
Если offset часто бывает большой (от 30-50 записей) то есть смысл немного оптимизировать цикл, т.е. не по одной странице смещаться, а сразу посчитать на сколько. Если в основном небольшой то лучше так оставить, меньше вычислений.
...
Рейтинг: 0 / 0
21.04.2016, 10:38
    #39220934
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
softwarerjenya7нужно считать например N-ю запись от текущей. сижу думаю над алгоритмом. ничего красивого в голову не приходит. может кто подскажет интересное решение?
Н-да.

Код: sql
1.
2.
3.
4.
tmp = старый_номер_записи + N;
новый_номер_страницы = старый_номер_страницы + tmp/5;
новый_номер_записи = tmp%5;
offset = 64 * новый_номер_страницы + 4 + 12 * новый_номер_записи;


новый номер страницы получается больше чем текущий. такого быть не может. страницы перед последней записи пусты. взять можно записи уже записанные - то есть взади.
...
Рейтинг: 0 / 0
21.04.2016, 10:47
    #39220951
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
jenya7,

ты на это не ответил 19086473 . Что из чего считаем? Как понимаю на выходе абсолютный адрес, на входе смещение и ... что? текущий адрес или текущая страница и номер на странице?
...
Рейтинг: 0 / 0
21.04.2016, 10:50
    #39220956
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Чуть допилил получение адреса по адресу и смещению.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
#define PAGE_SIZE 64 // Размер страницы
#define PAGE_MASK 0xFFFFFFC0 // Маска для получения начала страницы
#define HEADER_SIZE 4 // Размер заголовка страницы
#define RECORD_SIZE 12 // Размер записи

// Получение адреса новой записи
int get_record(int addr, int offset) {
	int new_addr = addr - offset * RECORD_SIZE;
	while(((addr ^ new_addr) & PAGE_MASK) != 0) {
		// new_addr и addr на разных страницах, корректируем 
		int page_cnt = ((addr & PAGE_MASK) - (new_addr & PAGE_MASK)) / PAGE_SIZE;
		new_addr -= page_cnt * HEADER_SIZE;
		addr -= page_cnt * PAGE_SIZE;
	}
	return new_addr;
}
...
Рейтинг: 0 / 0
21.04.2016, 11:00
    #39220972
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Dima TЧуть допилил получение адреса по адресу и смещению.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
#define PAGE_SIZE 64 // Размер страницы
#define PAGE_MASK 0xFFFFFFC0 // Маска для получения начала страницы
#define HEADER_SIZE 4 // Размер заголовка страницы
#define RECORD_SIZE 12 // Размер записи

// Получение адреса новой записи
int get_record(int addr, int offset) {
	int new_addr = addr - offset * RECORD_SIZE;
	while(((addr ^ new_addr) & PAGE_MASK) != 0) {
		// new_addr и addr на разных страницах, корректируем 
		int page_cnt = ((addr & PAGE_MASK) - (new_addr & PAGE_MASK)) / PAGE_SIZE;
		new_addr -= page_cnt * HEADER_SIZE;
		addr -= page_cnt * PAGE_SIZE;
	}
	return new_addr;
}



вау. оба варианта работают. громадное спасибо. завидую людям с мозгами. :)
...
Рейтинг: 0 / 0
21.04.2016, 11:03
    #39220980
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
jenya7новый номер страницы получается больше чем текущий. такого быть не может. страницы перед последней записи пусты. взять можно записи уже записанные - то есть взади.
Попробуйте нанять программиста
Попробуйте нанять аналитика писать ТЗ
Попробуйте нанять учителя русского языка
Попробуйте подать туда отрицательное смещение 1 .

1 Хз как определено деление с остатком для отрицательных в вашем компиляторе, а за исключением этого должно прокатить.
...
Рейтинг: 0 / 0
21.04.2016, 11:05
    #39220983
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Dima Tjenya7,

ты на это не ответил 19086473 . Что из чего считаем? Как понимаю на выходе абсолютный адрес, на входе смещение и ... что? текущий адрес или текущая страница и номер на странице?

это микросхема памяти - по адресу лежат данные - скажем 10-я запись от текущей - адресс записи - 92 – тут лежит первый байт записи – 92+12 - тут последний байт записи.
...
Рейтинг: 0 / 0
21.04.2016, 14:12
    #39221246
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
jenya7скажем 10-я запись от текущей
Смещение 10*12 + 4*(10 / 5)
...
Рейтинг: 0 / 0
21.04.2016, 14:19
    #39221257
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Dimitry Sibiryakovjenya7скажем 10-я запись от текущей
Смещение 10*12 + 4*(10 / 5)
Это верно только при смещении кратном 5.
...
Рейтинг: 0 / 0
21.04.2016, 14:27
    #39221270
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Dimitry Sibiryakovjenya7скажем 10-я запись от текущей
Смещение 10*12 + 4*(10 / 5)
да! гениально! общая длина записей + длина меток. Теперь текущий адрес - смещение и мы получили адрес требуемой записи. большое спасибо. :)
...
Рейтинг: 0 / 0
21.04.2016, 14:34
    #39221284
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Dima TDimitry Sibiryakovпропущено...

Смещение 10*12 + 4*(10 / 5)
Это верно только при смещении кратном 5.
если количество записей будет не 5 а 3 по идее тоже будет работать.
...
Рейтинг: 0 / 0
21.04.2016, 14:37
    #39221287
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
jenya7Dima Tпропущено...

Это верно только при смещении кратном 5.
если количество записей будет не 5 а 3 по идее тоже будет работать.
кстати если на странице остается пустое место его также можно добавить в вычисление как количество меток.
...
Рейтинг: 0 / 0
21.04.2016, 14:39
    #39221290
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
jenya7Dima Tпропущено...

Это верно только при смещении кратном 5.
если количество записей будет не 5 а 3 по идее тоже будет работать.
при смещении на 3 можем как остаться на текущей странице, так и перейти на соседнюю. Смотря в какой части страницы находимся.
...
Рейтинг: 0 / 0
21.04.2016, 14:45
    #39221295
jenya7
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Dima Tjenya7пропущено...

если количество записей будет не 5 а 3 по идее тоже будет работать.
при смещении на 3 можем как остаться на текущей странице, так и перейти на соседнюю. Смотря в какой части страницы находимся.
нужно добавить заглушку на страницу или сделать запись 20 байт. :)
...
Рейтинг: 0 / 0
21.04.2016, 15:00
    #39221317
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
Можно просто по адресу получить номер записи, изменить номер и получить обратно адрес
Код: sql
1.
2.
3.
номер = (адрес - адрес / 64 * 4) / 12
номер = номер - N
адрес = номер * 12 + номер / 4 * 5
...
Рейтинг: 0 / 0
21.04.2016, 15:02
    #39221320
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вычислить офсет в памяти в С.
чуть напутал
Код: sql
1.
адрес = номер * 12 + номер / 5 * 4
...
Рейтинг: 0 / 0
Форумы / Программирование [игнор отключен] [закрыт для гостей] / Вычислить офсет в памяти в С. / 25 сообщений из 39, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]