📄 mems_piecewise_seek.c
字号:
/* * DiskSim Storage Subsystem Simulation Environment (Version 4.0) * Revision Authors: John Bucy, Greg Ganger * Contributors: John Griffin, Jiri Schindler, Steve Schlosser * * Copyright (c) of Carnegie Mellon University, 2001-2008. * * This software is being provided by the copyright holders under the * following license. By obtaining, using and/or copying this software, * you agree that you have read, understood, and will comply with the * following terms and conditions: * * Permission to reproduce, use, and prepare derivative works of this * software is granted provided the copyright and "No Warranty" statements * are included with all reproductions and derivative works and associated * documentation. This software may also be redistributed without charge * provided that the copyright and "No Warranty" statements are included * in all redistributions. * * NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS. * CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER * EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED * TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY * OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE * MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT * TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT. * COPYRIGHT HOLDERS WILL BEAR NO LIABILITY FOR ANY USE OF THIS SOFTWARE * OR DOCUMENTATION. * */#include <math.h>#include "mems_global.h"#include "mems_piecewise_seek.h"/* this allows the output mechanism to be defined at compile time so * that you can compile the seek code on its own for testing. otherwise, * all logging is done to the disksim output file */#ifdef __SEPERATE__#define __OUTPUTFILE__ stderr#else#define __OUTPUTFILE__ outputfile#endif/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * These are helper functions for the piecewise-linear * seek time model. *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*//*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * * find_dist_nm() * * returns the distance in nanometers from start_offset * to end_offset. remember that these are _offsets_ from * the center of the sled. * * inputs: * mems_sled_t *sled - a pointer to the sled structure * coord_t *start - the starting coordinate * coord_t *end - the destination coordinate * * outputs: * double - the distance in nm from start_offset to * end_offset * * modifies: * nothing * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/doublefind_dist_nm(double start_offset, double end_offset) { double dist_nm; if (((start_offset > 0.0) && (end_offset > 0.0)) || ((start_offset < 0.0) && (end_offset < 0.0))) { /* we're on the same side of the sled */ dist_nm = fabs(end_offset - start_offset); } else { dist_nm = fabs(start_offset) + fabs(end_offset); } if (_VERBOSE_) { fprintf(__OUTPUTFILE__, "find_dist_nm:: start_offset = %f, end_offset = %f, dist_nm = %f\n", start_offset, end_offset, dist_nm); } return dist_nm;}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * * find_local_actuator_direction() * * returns the direction which the actuators are pulling * the sled, INWARD or OUTWARD. this is used to determine * if the actuators are helping the seek or hurting the * seek. see below for more. * * inputs: * double start_offset_nm - the start offset of the seek * double end_offset_nm - the end offset of the seek * int overall_actuator_direction - the direction the * actuators are acting. * * outputs: * int - INWARD if the actuators are pulling the sled * toward the center, OUTWARD if the actuators are * pulling toward the edge. * * modifies: * nothing * * what's really going on here: * * okay, what's the difference between INWARD, OUTWARD, OVERALL_POSITIVE, * OVERALL_NEGATIVE, etc, and what is this function for anyway? second question * first: given start and end offsets, this fuction tells you if the actuators * are pulling the sled toward the rest position (INWARD) or away from the rest * position (OUTWARD). for example, if the overall_actuator_direction is * OVERALL_POSITIVE, and the seek is entirely on the positive half of the square, * then the actuators are pulling the sled OUTWARD. when the seek crosses the * center line, then the function decides based the larger portion of the seek. * i think that answers the second question, too. it's used to determine when * the springs will help the seek and when they'll hurt. * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/int find_local_actuator_direction(double start_offset_nm, double end_offset_nm, int overall_actuator_direction) { if (_VERBOSE_) { fprintf(__OUTPUTFILE__, "find_local_actuator_direction:: start_offset_nm = %f, end_offset_nm = %f\n", start_offset_nm, end_offset_nm); if (overall_actuator_direction == OVERALL_POSITIVE) fprintf(__OUTPUTFILE__, "find_local_actuator_direction:: overall_actuator_direction = OVERALL_POSITIVE\n"); else fprintf(__OUTPUTFILE__, "find_local_actuator_direction:: overall_actuator_direction = OVERALL_NEGATIVE\n"); } if ((start_offset_nm <= 0.0) && (end_offset_nm <= 0.0)) { /* if the seek is on the negative side */ if (overall_actuator_direction == OVERALL_POSITIVE) { if (_VERBOSE_) fprintf(__OUTPUTFILE__, "find_local_actuator_direction:: local_actuator_direction is INWARD (1)\n"); return INWARD; } else { if (_VERBOSE_) fprintf(__OUTPUTFILE__, "find_local_actuator_direction:: local_actuator_direction is OUTWARD (2)\n"); return OUTWARD; } } else if ((start_offset_nm >= 0.0) && (end_offset_nm >= 0.0)) { /* if the seek is on the positive side */ if (overall_actuator_direction == OVERALL_POSITIVE) { if (_VERBOSE_) fprintf(__OUTPUTFILE__, "find_local_actuator_direction:: local_actuator_direction is OUTWARD (3)\n"); return OUTWARD; } else { if (_VERBOSE_) fprintf(__OUTPUTFILE__, "find_local_actuator_direction:: local_actuator_direction is OUTWARD (4)\n"); return INWARD; } } else { /* the seek crosses the centerline */ if (fabs(start_offset_nm) > fabs(end_offset_nm)) { /* i move more toward the center than away */ if (_VERBOSE_) fprintf(__OUTPUTFILE__, "find_local_actuator_direction:: local_actuator_direction is INWARD (5)\n"); return INWARD; } else { if (_VERBOSE_) fprintf(__OUTPUTFILE__, "find_local_actuator_direction:: local_actuator_direction is OUTWARD (6)\n"); return OUTWARD; } }} /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * * adjust_accel() * * returns the acceleration in the region given by the * start and end points. the acceleration at the two points * is the sum of the actuator acceleration and the spring * acceleration, which is given by * * [ actuator_accel * offset ] * [ -------- ] * spring_factor * [ length/2 ] * * the springs' restoring force is then a function of the * displacement (offset) and a fraction (spring_factor) of * the actuator force. put another way, if the spring_factor * is 0.10, then at the maximum offset the force from the springs * will be equal to 10% of the force from the actuators. * * the returned adjusted acceleration is the average of the * sums at the start and end points. * * inputs: * double accel - the base acceleration from the actuators * double spring_factor - the spring factor * double offset_1 - the offset of the starting point * double offset_2 - the offset of the ending point * double length - the length of the sled * int overall_actuator_direction - INWARD if the actuators * are pulling the sled toward the center, OUTWARD otherwise. * * outputs: * double - the adjusted acceleration for the region between * the start and end offsets, given the base actuator * acceleration, the spring_factor, the length of the * sled, and the overall actuator direction * * modifies: * nothing * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/double adjust_accel(double accel, double spring_factor, double offset_1, double offset_2, double length, int overall_actuator_direction) { double adjusted_accel; if (find_local_actuator_direction(offset_1, offset_2, overall_actuator_direction) == INWARD) { /* springs help */ if (_VERBOSE_) fprintf(__OUTPUTFILE__, "adjust_accel:: springs helped!\n"); } else { /* springs hurt */ spring_factor = -spring_factor; if (_VERBOSE_) fprintf(__OUTPUTFILE__, "adjust_accel:: springs hurt!\n"); } adjusted_accel = ( (accel + (accel * (spring_factor * (fabs(offset_1) / (length / 2)))) ) + (accel + (accel * (spring_factor * (fabs(offset_2) / (length / 2)))) ) ) / 2.0; if (_VERBOSE_) { fprintf(__OUTPUTFILE__, "adjust_accel:: offset_1 = %f, offset_2 = %f, accel = %f\n", offset_1, offset_2, accel); fprintf(__OUTPUTFILE__, "adjust_accel:: spring_factor = %f, length = %f\n", spring_factor, length); fprintf(__OUTPUTFILE__, "adjust_accel:: adjusted_accel = %f, diff = %f\n", adjusted_accel, ((adjusted_accel / accel) * 100.0) - 100.0); } return adjusted_accel;}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * * find_switch_offset_from_dist() * * computes the switchpoint offset between start_offset_nm * and end_offset_nm. this finds the offset which is the * midpoint between the two points. * * inputs: * double start_offset_nm - the starting offset * double end_offset_nm - the end offset * double dist_nm - the distance in nm between the two points * int direction - the direction of the seek * * outputs: * double - the offset of the midpoint in nm * * modifies: * nothing * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/doublefind_switch_offset_from_dist (double start_offset_nm, double end_offset_nm, double dist_nm, int direction) { double switch_offset_nm; if (direction == OVERALL_POSITIVE) { switch_offset_nm = start_offset_nm + (dist_nm / 2); } else { switch_offset_nm = start_offset_nm - (dist_nm / 2); } return switch_offset_nm;}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * * find_overall_seek_direction() * * finds the direction of the seek - OVERALL_POSITIVE * or OVERALL_NEGATIVE * * inputs: * double start_offset_nm - the starting offset * double end_offset_nm - the end offset * * outputs: * int - OVERALL_POSITIVE if the seek is in the positive * direction, OVERALL_NEGATIVE if negative. * * modifies: * nothing * *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/intfind_overall_seek_direction(double start_offset_nm, double end_offset_nm) { if (end_offset_nm > start_offset_nm) { return OVERALL_POSITIVE; } else { return OVERALL_NEGATIVE; }}/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- * * find_seek_time_piecewise() * * this is the guts of the seek code. find_seek_time_piecewise() * returns the time to seek from start_offset_nm to end_offset_nm * given the various parameters. it assumes that the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -